libxml-ruby 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/CHANGELOG +49 -0
  2. data/LICENSE +22 -0
  3. data/README +129 -0
  4. data/Rakefile +197 -0
  5. data/TODO +84 -0
  6. data/ext/xml/cbg.c +76 -0
  7. data/ext/xml/extconf.rb +95 -0
  8. data/ext/xml/libxml.c +86 -0
  9. data/ext/xml/libxml.h +79 -0
  10. data/ext/xml/ruby_xml_attr.c +372 -0
  11. data/ext/xml/ruby_xml_attr.h +21 -0
  12. data/ext/xml/ruby_xml_attribute.c +224 -0
  13. data/ext/xml/ruby_xml_attribute.h +21 -0
  14. data/ext/xml/ruby_xml_document.c +1159 -0
  15. data/ext/xml/ruby_xml_document.h +27 -0
  16. data/ext/xml/ruby_xml_dtd.c +168 -0
  17. data/ext/xml/ruby_xml_dtd.h +17 -0
  18. data/ext/xml/ruby_xml_input_cbg.c +167 -0
  19. data/ext/xml/ruby_xml_input_cbg.h +21 -0
  20. data/ext/xml/ruby_xml_node.c +2052 -0
  21. data/ext/xml/ruby_xml_node.h +28 -0
  22. data/ext/xml/ruby_xml_node_set.c +197 -0
  23. data/ext/xml/ruby_xml_node_set.h +26 -0
  24. data/ext/xml/ruby_xml_ns.c +153 -0
  25. data/ext/xml/ruby_xml_ns.h +21 -0
  26. data/ext/xml/ruby_xml_parser.c +1363 -0
  27. data/ext/xml/ruby_xml_parser.h +31 -0
  28. data/ext/xml/ruby_xml_parser_context.c +715 -0
  29. data/ext/xml/ruby_xml_parser_context.h +22 -0
  30. data/ext/xml/ruby_xml_sax_parser.c +181 -0
  31. data/ext/xml/ruby_xml_sax_parser.h +21 -0
  32. data/ext/xml/ruby_xml_schema.c +142 -0
  33. data/ext/xml/ruby_xml_schema.h +16 -0
  34. data/ext/xml/ruby_xml_tree.c +43 -0
  35. data/ext/xml/ruby_xml_tree.h +12 -0
  36. data/ext/xml/ruby_xml_xinclude.c +20 -0
  37. data/ext/xml/ruby_xml_xinclude.h +13 -0
  38. data/ext/xml/ruby_xml_xpath.c +357 -0
  39. data/ext/xml/ruby_xml_xpath.h +24 -0
  40. data/ext/xml/ruby_xml_xpath_context.c +124 -0
  41. data/ext/xml/ruby_xml_xpath_context.h +24 -0
  42. data/ext/xml/ruby_xml_xpointer.c +100 -0
  43. data/ext/xml/ruby_xml_xpointer.h +27 -0
  44. data/ext/xml/ruby_xml_xpointer_context.c +22 -0
  45. data/ext/xml/ruby_xml_xpointer_context.h +18 -0
  46. data/tests/copy_bug.rb +21 -0
  47. data/tests/dtd-test.rb +24 -0
  48. data/tests/model/default_validation_bug.rb +0 -0
  49. data/tests/model/rubynet.xml +78 -0
  50. data/tests/model/rubynet_project +13 -0
  51. data/tests/model/xinclude.xml +5 -0
  52. data/tests/runner.rb +13 -0
  53. data/tests/schema-test.rb +74 -0
  54. data/tests/tc_default_validation.rb +0 -0
  55. data/tests/tc_xml_document.rb +51 -0
  56. data/tests/tc_xml_document_write.rb +25 -0
  57. data/tests/tc_xml_document_write2.rb +55 -0
  58. data/tests/tc_xml_document_write3.rb +97 -0
  59. data/tests/tc_xml_node.rb +59 -0
  60. data/tests/tc_xml_node2.rb +26 -0
  61. data/tests/tc_xml_node_set.rb +25 -0
  62. data/tests/tc_xml_node_xlink.rb +28 -0
  63. data/tests/tc_xml_parser.rb +175 -0
  64. data/tests/tc_xml_parser2.rb +17 -0
  65. data/tests/tc_xml_parser3.rb +23 -0
  66. data/tests/tc_xml_parser4.rb +33 -0
  67. data/tests/tc_xml_parser5.rb +27 -0
  68. data/tests/tc_xml_parser6.rb +23 -0
  69. data/tests/tc_xml_parser7.rb +28 -0
  70. data/tests/tc_xml_parser_context.rb +89 -0
  71. data/tests/tc_xml_xinclude.rb +30 -0
  72. data/tests/tc_xml_xpath.rb +23 -0
  73. data/tests/tc_xml_xpointer.rb +78 -0
  74. metadata +144 -0
data/ext/xml/cbg.c ADDED
@@ -0,0 +1,76 @@
1
+ #include <string.h>
2
+ #include <libxml/xmlIO.h>
3
+ #include "ruby.h"
4
+
5
+ /*
6
+ int xmlRegisterInputCallbacks (xmlInputMatchCallback matchFunc,
7
+ xmlInputOpenCallback openFunc,
8
+ xmlInputReadCallback readFunc,
9
+ xmlInputCloseCallback closeFunc);
10
+
11
+
12
+ int (*xmlInputMatchCallback) (char const *filename);
13
+ void* (*xmlInputOpenCallback) (char const *filename);
14
+ int (*xmlInputReadCallback) (void *context,
15
+ char *buffer,
16
+ int len);
17
+ int (*xmlInputCloseCallback) (void *context);
18
+ */
19
+
20
+ typedef struct deb_doc_context {
21
+ char *buffer;
22
+ char *bpos;
23
+ int remaining;
24
+ } deb_doc_context;
25
+
26
+ int deb_Match (char const *filename) {
27
+ fprintf( stderr, "deb_Match: %s\n", filename );
28
+ if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "deb://", 6)) {
29
+ return(1);
30
+ }
31
+ return(0);
32
+ }
33
+
34
+ void* deb_Open (char const *filename) {
35
+ deb_doc_context *deb_doc;
36
+ VALUE res;
37
+
38
+ deb_doc = (deb_doc_context*)malloc( sizeof(deb_doc_context) );
39
+
40
+ res = rb_funcall( rb_funcall( rb_mKernel, rb_intern("const_get"), 1, rb_str_new2("DEBSystem") ),
41
+ rb_intern("document_query"), 1, rb_str_new2(filename));
42
+ deb_doc->buffer = strdup( StringValuePtr(res) );
43
+ //deb_doc->buffer = strdup("<serepes>serepes</serepes>");
44
+
45
+ deb_doc->bpos = deb_doc->buffer;
46
+ deb_doc->remaining = strlen(deb_doc->buffer);
47
+ return deb_doc;
48
+ }
49
+
50
+ int deb_Read (void *context, char *buffer, int len) {
51
+ deb_doc_context *deb_doc;
52
+ int ret_len;
53
+ deb_doc = (deb_doc_context*)context;
54
+
55
+ if (len >= deb_doc->remaining) {
56
+ ret_len = deb_doc->remaining;
57
+ } else {
58
+ ret_len = len;
59
+ }
60
+ deb_doc->remaining -= ret_len;
61
+ strncpy( buffer, deb_doc->bpos, ret_len );
62
+ deb_doc->bpos += ret_len;
63
+
64
+ return ret_len;
65
+ }
66
+
67
+ int deb_Close (void *context) {
68
+ free( ((deb_doc_context*)context)->buffer );
69
+ free( context );
70
+ return 1;
71
+ }
72
+
73
+
74
+ void deb_register_cbg() {
75
+ xmlRegisterInputCallbacks( deb_Match, deb_Open, deb_Read, deb_Close );
76
+ }
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'mkmf'
4
+
5
+ if defined?(CFLAGS)
6
+ if CFLAGS.index(CONFIG['CCDLFLAGS'])
7
+ $CFLAGS = CFLAGS
8
+ else
9
+ $CFLAGS = CFLAGS + ' ' + CONFIG['CCDLFLAGS']
10
+ end
11
+ else
12
+ $CFLAGS = CONFIG['CFLAGS']
13
+ end
14
+ $LDFLAGS = CONFIG['LDFLAGS']
15
+ $LIBPATH.push(Config::CONFIG['libdir'])
16
+
17
+ def crash(str)
18
+ printf(" extconf failure: %s\n", str)
19
+ exit 1
20
+ end
21
+
22
+ dir_config('iconv')
23
+ dir_config('xml2')
24
+ dir_config('zlib')
25
+
26
+ have_library('socket','socket')
27
+ have_library('nsl','gethostbyname')
28
+
29
+ unless have_library('m', 'atan')
30
+ # try again for gcc 4.0
31
+ saveflags = $CFLAGS
32
+ $CFLAGS += ' -fno-builtin'
33
+ unless have_library('m', 'atan')
34
+ crash('need libm')
35
+ end
36
+ $CFLAGS = saveflags
37
+ end
38
+
39
+ unless have_library('z', 'inflate')
40
+ crash('need zlib')
41
+ else
42
+ $defs.push('-DHAVE_ZLIB_H')
43
+ end
44
+
45
+ unless have_library('iconv','iconv_open') or have_library('c','iconv_open') or
46
+ have_library('recode','iconv_open')
47
+ crash(<<EOL)
48
+ need libiconv.
49
+
50
+ Install the libiconv or try passing one of the following options
51
+ to extconf.rb:
52
+
53
+ --with-iconv-dir=/path/to/iconv
54
+ --with-iconv-lib=/path/to/iconv/lib
55
+ --with-iconv-include=/path/to/iconv/include
56
+ EOL
57
+ end
58
+
59
+ unless have_library('xml2', 'xmlParseDoc')
60
+ crash(<<EOL)
61
+ need libxml2.
62
+
63
+ Install the library or try one of the following options to extconf.rb:
64
+
65
+ --with-xml2-dir=/path/to/libxml2
66
+ --with-xml2-lib=/path/to/libxml2/lib
67
+ --with-xml2-include=/path/to/libxml2/include
68
+ EOL
69
+ end
70
+
71
+ unless have_library('xml2', 'xmlDocFormatDump')
72
+ crash('Your version of libxml2 is too old. Please upgrade.')
73
+ end
74
+
75
+ unless have_func('docbCreateFileParserCtxt')
76
+ crash('Need docbCreateFileParserCtxt')
77
+ end
78
+
79
+ $LDFLAGS << ' ' + `xslt-config --libs`.chomp
80
+ $LDFLAGS << ' ' + `xml2-config --libs`.chomp
81
+
82
+ $CFLAGS << ' ' + `xslt-config --cflags`.chomp
83
+ $CFLAGS << ' ' + `xml2-config --cflags`.chomp
84
+ $CFLAGS = '-g -Wall ' + $CFLAGS
85
+
86
+ create_header()
87
+ create_makefile('xml/libxml')
88
+
89
+ # Quick hack around a problem building on OSX
90
+ if RUBY_PLATFORM =~ /darwin/
91
+ mf = File.read('Makefile')
92
+ File.open('Makefile','w+') do |f|
93
+ f << mf.gsub(/^CFLAGS\s+=\s+(.*)/) { "CFLAGS = #{$1.gsub('-fno-common','')}" }
94
+ end
95
+ end
data/ext/xml/libxml.c ADDED
@@ -0,0 +1,86 @@
1
+ /* $Id: libxml.c,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ #include "libxml.h"
6
+
7
+ /* Ruby's util.h has ruby_strdup */
8
+ #include "util.h"
9
+
10
+ #ifdef xmlMalloc
11
+ #undef xmlMalloc
12
+ #endif
13
+ #ifdef xmlRealloc
14
+ #undef xmlRealloc
15
+ #endif
16
+ #ifdef xmlMemStrdup
17
+ #undef xmlMemStrdup
18
+ #endif
19
+ #ifdef xmlMemFree
20
+ #undef xmlMemFree
21
+ #endif
22
+
23
+ #ifdef RubyMemMalloc
24
+ #undef RubyMemMalloc
25
+ #endif
26
+ #ifdef RubyMemRealloc
27
+ #undef RubyMemRealloc
28
+ #endif
29
+ #ifdef RubyMemStrdup
30
+ #undef RubyMemStrdup
31
+ #endif
32
+ #ifdef RubyMemFree
33
+ #undef RubyMemFree
34
+ #endif
35
+
36
+ #define RubyMemFree ruby_xfree
37
+ #define RubyMemRealloc ruby_xrealloc
38
+ #define RubyMemMalloc ruby_xmalloc
39
+ #define RubyMemStrdup ruby_strdup
40
+
41
+ VALUE mXML;
42
+
43
+ static xmlFreeFunc freeFunc = NULL;
44
+ static xmlMallocFunc mallocFunc = NULL;
45
+ static xmlReallocFunc reallocFunc = NULL;
46
+ static xmlStrdupFunc strdupFunc = NULL;
47
+
48
+ void
49
+ Init_libxml(void) {
50
+ /* Some libxml memory goo that should be done before anything else */
51
+ xmlMemGet((xmlFreeFunc *) & freeFunc,
52
+ (xmlMallocFunc *) & mallocFunc,
53
+ (xmlReallocFunc *) & reallocFunc,
54
+ (xmlStrdupFunc *) & strdupFunc);
55
+
56
+ if (xmlMemSetup((xmlFreeFunc)RubyMemFree, (xmlMallocFunc)RubyMemMalloc,
57
+ (xmlReallocFunc)RubyMemRealloc, (xmlStrdupFunc)RubyMemStrdup) != 0)
58
+ rb_fatal("could not install the memory handlers for libxml");
59
+ xmlInitParser();
60
+
61
+ mXML = rb_define_module("XML");
62
+
63
+ rb_define_const(mXML, "XML_NAMESPACE", rb_str_new2((const char*)XML_XML_NAMESPACE));
64
+
65
+ ruby_init_parser();
66
+ ruby_init_xml_parser_context();
67
+ ruby_init_xml_attr();
68
+ ruby_init_xml_attribute();
69
+ ruby_init_xml_document();
70
+ ruby_init_xml_node();
71
+ ruby_init_xml_node_set();
72
+ ruby_init_xml_ns();
73
+ ruby_init_xml_sax_parser();
74
+ ruby_init_xml_tree();
75
+ ruby_init_xml_xinclude();
76
+ ruby_init_xml_xpath();
77
+ ruby_init_xml_xpath_context();
78
+ ruby_init_xml_xpointer();
79
+ ruby_init_xml_xpointer_context();
80
+ ruby_init_input_callbacks(); /* MUFF */
81
+ ruby_init_xml_dtd(); /* MUFF */
82
+ ruby_init_xml_schema(); /* MUFF */
83
+
84
+ ruby_xml_parser_default_substitute_entities_set(cXMLParser, Qtrue);
85
+ ruby_xml_parser_default_load_external_dtd_set(cXMLParser, Qtrue);
86
+ }
data/ext/xml/libxml.h ADDED
@@ -0,0 +1,79 @@
1
+ /* Please see the LICENSE file for copyright and distribution information */
2
+
3
+ #ifndef __RUBY_LIBXML_H__
4
+ #define __RUBY_LIBXML_H__
5
+
6
+ /* Don't nuke this block! It is used for automatically updating the
7
+ * versions below. VERSION = string formatting, VERNUM = numbered
8
+ * version for inline testing: increment both or none at all. */
9
+ #define RUBY_LIBXML_VERSION "0.3.6"
10
+ #define RUBY_LIBXML_VERNUM 036
11
+
12
+ #include <ruby.h>
13
+ #include <rubyio.h>
14
+ #include <util.h>
15
+ #include <libxml/parser.h>
16
+ #include <libxml/parserInternals.h>
17
+ #include <libxml/debugXML.h>
18
+ #include <libxml/xmlversion.h>
19
+ #include <libxml/xmlmemory.h>
20
+ #include <libxml/xpath.h>
21
+ #include <libxml/valid.h>
22
+ #include <libxml/catalog.h>
23
+ #ifdef LIBXML_DEBUG_ENABLED
24
+ #include <libxml/xpathInternals.h>
25
+ #endif
26
+ #ifdef LIBXML_XINCLUDE_ENABLED
27
+ #include <libxml/xinclude.h>
28
+ #endif
29
+ #ifdef LIBXML_XPTR_ENABLED
30
+ #include <libxml/xpointer.h>
31
+ #endif
32
+
33
+ #define RUBY_LIBXML_SRC_TYPE_NULL 0
34
+ #define RUBY_LIBXML_SRC_TYPE_FILE 1
35
+ #define RUBY_LIBXML_SRC_TYPE_STRING 2
36
+ #define RUBY_LIBXML_SRC_TYPE_IO 3
37
+ #define RUBY_LIBXML_SRC_TYPE_XPATH 4
38
+
39
+ typedef struct rx_file_data {
40
+ VALUE filename; /* Filename/path to self */
41
+ } rx_file_data;
42
+
43
+ typedef struct rx_io_data {
44
+ VALUE io;
45
+ } rx_io_data;
46
+
47
+ typedef struct rx_string_data {
48
+ VALUE str;
49
+ } rx_string_data;
50
+
51
+ typedef struct rx_xpath_data {
52
+ VALUE ctxt;
53
+ } rx_xpath_data;
54
+
55
+ #include "ruby_xml_attr.h"
56
+ #include "ruby_xml_attribute.h"
57
+ #include "ruby_xml_document.h"
58
+ #include "ruby_xml_node.h"
59
+ #include "ruby_xml_node_set.h"
60
+ #include "ruby_xml_ns.h"
61
+ #include "ruby_xml_parser.h"
62
+ #include "ruby_xml_parser_context.h"
63
+ #include "ruby_xml_sax_parser.h"
64
+ #include "ruby_xml_tree.h"
65
+ #include "ruby_xml_xinclude.h"
66
+ #include "ruby_xml_xpath.h"
67
+ #include "ruby_xml_xpath_context.h"
68
+ #include "ruby_xml_xpointer.h"
69
+ #include "ruby_xml_xpointer_context.h"
70
+ #include "ruby_xml_input_cbg.h"
71
+ #include "ruby_xml_dtd.h"
72
+ #include "ruby_xml_schema.h"
73
+
74
+ extern VALUE mXML;
75
+
76
+ void ruby_init_parser(void);
77
+ void ruby_xml_parser_free(ruby_xml_parser *rxp);
78
+
79
+ #endif
@@ -0,0 +1,372 @@
1
+ /* $Id: ruby_xml_attr.c,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ #include "libxml.h"
6
+ #include "ruby_xml_attr.h"
7
+
8
+ VALUE cXMLAttr;
9
+
10
+ void
11
+ ruby_xml_attr_free(ruby_xml_attr *rxa) {
12
+ if (rxa->attr != NULL && !rxa->is_ptr) {
13
+ xmlUnlinkNode((xmlNodePtr)rxa->attr);
14
+ xmlFreeNode((xmlNodePtr)rxa->attr);
15
+ rxa->attr = NULL;
16
+ }
17
+
18
+ free(rxa);
19
+ }
20
+
21
+
22
+ /*
23
+ * call-seq:
24
+ * attr.child => node
25
+ *
26
+ * Obtain this attribute's child attribute(s).
27
+ */
28
+ VALUE
29
+ ruby_xml_attr_child_get(VALUE self) {
30
+ ruby_xml_attr *rxa;
31
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
32
+ if (rxa->attr->children == NULL)
33
+ return(Qnil);
34
+ else
35
+ return(ruby_xml_node_new2(cXMLNode, rxa->xd, rxa->attr->children));
36
+ }
37
+
38
+
39
+ /*
40
+ * call-seq:
41
+ * attr.child? => (true|false)
42
+ *
43
+ * Determine whether this attribute has child attributes.
44
+ */
45
+ VALUE
46
+ ruby_xml_attr_child_q(VALUE self) {
47
+ ruby_xml_attr *rxa;
48
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
49
+ if (rxa->attr->children == NULL)
50
+ return(Qfalse);
51
+ else
52
+ return(Qtrue);
53
+ }
54
+
55
+
56
+ /*
57
+ * call-seq:
58
+ * attr.doc => document
59
+ *
60
+ * Obtain the XML::Document this attribute is associated with,
61
+ * if any.
62
+ */
63
+ VALUE
64
+ ruby_xml_attr_doc_get(VALUE self) {
65
+ ruby_xml_attr *rxa;
66
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
67
+ if (rxa->attr->doc == NULL)
68
+ return(Qnil);
69
+ else
70
+ return(ruby_xml_document_new(cXMLDocument, rxa->attr->doc));
71
+ }
72
+
73
+
74
+ /*
75
+ * call-seq:
76
+ * attr.doc? => (true|false)
77
+ *
78
+ * Determine whether this attribute is associated with an
79
+ * XML::Document.
80
+ */
81
+ VALUE
82
+ ruby_xml_attr_doc_q(VALUE self) {
83
+ ruby_xml_attr *rxa;
84
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
85
+ if (rxa->attr->doc == NULL)
86
+ return(Qfalse);
87
+ else
88
+ return(Qtrue);
89
+ }
90
+
91
+
92
+ /*
93
+ * call-seq:
94
+ * attr.last => node
95
+ *
96
+ * Obtain the last attribute.
97
+ */
98
+ VALUE
99
+ ruby_xml_attr_last_get(VALUE self) {
100
+ ruby_xml_attr *rxa;
101
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
102
+ if (rxa->attr->last == NULL)
103
+ return(Qnil);
104
+ else
105
+ return(ruby_xml_node_new2(cXMLNode, rxa->xd, rxa->attr->last));
106
+ }
107
+
108
+
109
+ /*
110
+ * call-seq:
111
+ * attr.last? => (true|false)
112
+ *
113
+ * Determine whether this is the last attribute.
114
+ */
115
+ VALUE
116
+ ruby_xml_attr_last_q(VALUE self) {
117
+ ruby_xml_attr *rxa;
118
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
119
+ if (rxa->attr->last == NULL)
120
+ return(Qfalse);
121
+ else
122
+ return(Qtrue);
123
+ }
124
+
125
+
126
+ static void
127
+ ruby_xml_attr_mark(ruby_xml_attr *rxa) {
128
+ if (rxa == NULL) return;
129
+ if (!NIL_P(rxa->xd)) rb_gc_mark(rxa->xd);
130
+ }
131
+
132
+
133
+ /*
134
+ * call-seq:
135
+ * attr.name => "name"
136
+ *
137
+ * Obtain this attribute's name.
138
+ */
139
+ VALUE
140
+ ruby_xml_attr_name_get(VALUE self) {
141
+ ruby_xml_attr *rxa;
142
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
143
+
144
+ if (rxa->attr->name == NULL)
145
+ return(Qnil);
146
+ else
147
+ return(rb_str_new2((const char*)rxa->attr->name));
148
+ }
149
+
150
+
151
+ VALUE
152
+ ruby_xml_attr_new(VALUE class, VALUE xd, xmlAttrPtr attr) {
153
+ ruby_xml_attr *rxa;
154
+
155
+ rxa = ALLOC(ruby_xml_attr);
156
+ rxa->attr = attr;
157
+ rxa->xd = xd;
158
+ rxa->is_ptr = 0;
159
+ return(Data_Wrap_Struct(class, ruby_xml_attr_mark,
160
+ ruby_xml_attr_free, rxa));
161
+ }
162
+
163
+
164
+ VALUE
165
+ ruby_xml_attr_new2(VALUE class, VALUE xd, xmlAttrPtr attr) {
166
+ ruby_xml_attr *rxa;
167
+
168
+ rxa = ALLOC(ruby_xml_attr);
169
+ rxa->attr = xmlCopyProp(attr->parent, attr);
170
+ rxa->xd = xd;
171
+ rxa->is_ptr = 0;
172
+ return(Data_Wrap_Struct(class, ruby_xml_attr_mark,
173
+ ruby_xml_attr_free, rxa));
174
+ }
175
+
176
+
177
+ /*
178
+ * call-seq:
179
+ * attr.next => node
180
+ *
181
+ * Obtain the next attribute.
182
+ */
183
+ VALUE
184
+ ruby_xml_attr_next_get(VALUE self) {
185
+ ruby_xml_attr *rxa;
186
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
187
+ if (rxa->attr->next == NULL)
188
+ return(Qnil);
189
+ else
190
+ return(ruby_xml_attr_new(cXMLAttr, rxa->xd, rxa->attr->next));
191
+ }
192
+
193
+
194
+ /*
195
+ * call-seq:
196
+ * attr.next? => (true|false)
197
+ *
198
+ * Determine whether there is a next attribute.
199
+ */
200
+ VALUE
201
+ ruby_xml_attr_next_q(VALUE self) {
202
+ ruby_xml_attr *rxa;
203
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
204
+ if (rxa->attr->next == NULL)
205
+ return(Qfalse);
206
+ else
207
+ return(Qtrue);
208
+ }
209
+
210
+
211
+ /*
212
+ * call-seq:
213
+ * attr.type_name => "attribute"
214
+ *
215
+ * Obtain this attribute node's type name.
216
+ */
217
+ VALUE
218
+ ruby_xml_attr_node_type_name(VALUE self) {
219
+ /* I think libxml2's naming convention blows monkey ass */
220
+ return(rb_str_new2("attribute"));
221
+ }
222
+
223
+
224
+ /*
225
+ * call-seq:
226
+ * attr.ns => namespace
227
+ *
228
+ * Obtain this attribute's associated XML::NS, if any.
229
+ */
230
+ VALUE
231
+ ruby_xml_attr_ns_get(VALUE self) {
232
+ ruby_xml_attr *rxa;
233
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
234
+ if (rxa->attr->ns == NULL)
235
+ return(Qnil);
236
+ else
237
+ return(ruby_xml_ns_new2(cXMLNS, rxa->xd, rxa->attr->ns));
238
+ }
239
+
240
+
241
+ /*
242
+ * call-seq:
243
+ * attr.ns? => (true|false)
244
+ *
245
+ * Determine whether this attribute has an associated
246
+ * namespace.
247
+ */
248
+ VALUE
249
+ ruby_xml_attr_ns_q(VALUE self) {
250
+ ruby_xml_attr *rxa;
251
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
252
+ if (rxa->attr->ns == NULL)
253
+ return(Qfalse);
254
+ else
255
+ return(Qtrue);
256
+ }
257
+
258
+
259
+ /*
260
+ * call-seq:
261
+ * attr.parent => node
262
+ *
263
+ * Obtain this attribute node's parent.
264
+ */
265
+ VALUE
266
+ ruby_xml_attr_parent_get(VALUE self) {
267
+ ruby_xml_attr *rxa;
268
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
269
+ if (rxa->attr->parent == NULL)
270
+ return(Qnil);
271
+ else
272
+ return(ruby_xml_node_new2(cXMLNode, rxa->xd, rxa->attr->parent));
273
+ }
274
+
275
+
276
+ /*
277
+ * call-seq:
278
+ * attr.parent? => (true|false)
279
+ *
280
+ * Determine whether this attribute has a parent.
281
+ */
282
+ VALUE
283
+ ruby_xml_attr_parent_q(VALUE self) {
284
+ ruby_xml_attr *rxa;
285
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
286
+ if (rxa->attr->parent == NULL)
287
+ return(Qfalse);
288
+ else
289
+ return(Qtrue);
290
+ }
291
+
292
+
293
+ /*
294
+ * call-seq:
295
+ * attr.prev => node
296
+ *
297
+ * Obtain the previous attribute.
298
+ */
299
+ VALUE
300
+ ruby_xml_attr_prev_get(VALUE self) {
301
+ ruby_xml_attr *rxa;
302
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
303
+ if (rxa->attr->prev == NULL)
304
+ return(Qnil);
305
+ else
306
+ return(ruby_xml_attr_new(cXMLAttr, rxa->xd, rxa->attr->prev));
307
+ }
308
+
309
+
310
+ /*
311
+ * call-seq:
312
+ * attr.prev? => (true|false)
313
+ *
314
+ * Determine whether there is a previous attribute.
315
+ */
316
+ VALUE
317
+ ruby_xml_attr_prev_q(VALUE self) {
318
+ ruby_xml_attr *rxa;
319
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
320
+ if (rxa->attr->prev == NULL)
321
+ return(Qfalse);
322
+ else
323
+ return(Qtrue);
324
+ }
325
+
326
+
327
+ /*
328
+ * call-seq:
329
+ * attr.value => "value"
330
+ *
331
+ * Obtain the value of this attribute.
332
+ */
333
+ VALUE
334
+ ruby_xml_attr_value(VALUE self) {
335
+ ruby_xml_attr *rxa;
336
+ xmlChar *value;
337
+
338
+ Data_Get_Struct(self, ruby_xml_attr, rxa);
339
+ if (ruby_xml_attr_parent_q(self) == Qtrue) {
340
+ value = xmlGetProp(rxa->attr->parent, rxa->attr->name);
341
+ if (value != NULL)
342
+ return(rb_str_new2((const char*)value));
343
+ }
344
+ return(Qnil);
345
+ }
346
+
347
+ // Rdoc needs to know
348
+ #ifdef RDOC_NEVER_DEFINED
349
+ mXML = rb_define_module("XML");
350
+ #endif
351
+
352
+ void
353
+ ruby_init_xml_attr(void) {
354
+ cXMLAttr = rb_define_class_under(mXML, "Attr", rb_cObject);
355
+ rb_define_method(cXMLAttr, "child", ruby_xml_attr_child_get, 0);
356
+ rb_define_method(cXMLAttr, "child?", ruby_xml_attr_child_q, 0);
357
+ rb_define_method(cXMLAttr, "doc", ruby_xml_attr_doc_get, 0);
358
+ rb_define_method(cXMLAttr, "doc?", ruby_xml_attr_doc_q, 0);
359
+ rb_define_method(cXMLAttr, "last", ruby_xml_attr_last_get, 0);
360
+ rb_define_method(cXMLAttr, "last?", ruby_xml_attr_last_q, 0);
361
+ rb_define_method(cXMLAttr, "name", ruby_xml_attr_name_get, 0);
362
+ rb_define_method(cXMLAttr, "next", ruby_xml_attr_next_get, 0);
363
+ rb_define_method(cXMLAttr, "next?", ruby_xml_attr_next_q, 0);
364
+ rb_define_method(cXMLAttr, "node_type_name", ruby_xml_attr_node_type_name, 0);
365
+ rb_define_method(cXMLAttr, "ns", ruby_xml_attr_ns_get, 0);
366
+ rb_define_method(cXMLAttr, "ns?", ruby_xml_attr_ns_q, 0);
367
+ rb_define_method(cXMLAttr, "parent", ruby_xml_attr_parent_get, 0);
368
+ rb_define_method(cXMLAttr, "parent?", ruby_xml_attr_parent_q, 0);
369
+ rb_define_method(cXMLAttr, "prev", ruby_xml_attr_prev_get, 0);
370
+ rb_define_method(cXMLAttr, "prev?", ruby_xml_attr_prev_q, 0);
371
+ rb_define_method(cXMLAttr, "value", ruby_xml_attr_value, 0);
372
+ }