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
@@ -0,0 +1,27 @@
1
+ /* $Id: ruby_xml_document.h,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
+ #ifndef __RUBY_XML_DOCUMENT__
6
+ #define __RUBY_XML_DOCUMENT__
7
+
8
+ extern VALUE cXMLDocument;
9
+
10
+ typedef struct rxp_document {
11
+ xmlDocPtr doc; /* Tree/DOM interface */
12
+ int data_type; /* The data type referenced by *data */
13
+ void *data; /* Pointer to an external structure of options */
14
+ int is_ptr; /* Determines if this object owns its data or points to it someplace else */
15
+ VALUE xmlver; /* T_STRING with the xml version */
16
+ } ruby_xml_document;
17
+
18
+ VALUE ruby_xml_document_filename_get(VALUE self);
19
+ void ruby_xml_document_free(ruby_xml_document *rxd);
20
+ VALUE ruby_xml_document_new(VALUE class, xmlDocPtr doc);
21
+ VALUE ruby_xml_document_new2(VALUE class, VALUE xmlver);
22
+ VALUE ruby_xml_document_new3(VALUE class);
23
+ VALUE ruby_xml_document_new4(VALUE class, xmlDocPtr doc);
24
+ VALUE ruby_xml_document_root_get(VALUE self);
25
+ void ruby_init_xml_document(void);
26
+
27
+ #endif
@@ -0,0 +1,168 @@
1
+ #include "libxml.h"
2
+ #include "ruby_xml_dtd.h"
3
+
4
+ VALUE cXMLDtd;
5
+
6
+ void
7
+ ruby_xml_dtd_free(ruby_xml_dtd *rxdtd) {
8
+ if (rxdtd->dtd != NULL) {
9
+ xmlFreeDtd(rxdtd->dtd);
10
+ rxdtd->dtd = NULL;
11
+ }
12
+
13
+ free(rxdtd);
14
+ }
15
+
16
+ static void
17
+ ruby_xml_dtd_mark(ruby_xml_dtd *rxdtd) {
18
+ return;
19
+ //if (rxdtd == NULL) return;
20
+ //if (!NIL_P(rxd->xmlver)) rb_gc_mark(rxd->xmlver);
21
+ }
22
+
23
+ /*
24
+ * call-seq:
25
+ * XML::DTD.new("public system") => dtd
26
+ * XML::DTD.new("public", "system") => dtd
27
+ *
28
+ * Create a new DTD from the specified public and system
29
+ * identifiers.
30
+ */
31
+ VALUE
32
+ ruby_xml_dtd_initialize(int argc, VALUE *argv, VALUE class) {
33
+ ruby_xml_dtd *rxdtd;
34
+ VALUE external, system, dtd_string;
35
+ xmlParserInputBufferPtr buffer;
36
+ xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
37
+ xmlChar *new_string;
38
+
39
+ // 1 argument -- string --> parsujeme jako dtd
40
+ // 2 argumenty -- public, system --> bude se hledat
41
+ switch (argc) {
42
+ case 2:
43
+ rb_scan_args(argc, argv, "20", &external, &system);
44
+
45
+ Check_Type(external, T_STRING);
46
+ Check_Type(system, T_STRING);
47
+ rxdtd = ALLOC(ruby_xml_dtd);
48
+ rxdtd->dtd = xmlParseDTD( (xmlChar*)StringValuePtr(external),
49
+ (xmlChar*)StringValuePtr(system) );
50
+ if (rxdtd->dtd == NULL) {
51
+ free(rxdtd);
52
+ return(Qfalse);
53
+ }
54
+
55
+ xmlSetTreeDoc( (xmlNodePtr)rxdtd->dtd, NULL );
56
+ return( Data_Wrap_Struct(cXMLDtd, ruby_xml_dtd_mark, ruby_xml_dtd_free, rxdtd) );
57
+ break;
58
+
59
+ /*
60
+ SV *
61
+ new(CLASS, external, system)
62
+ char * CLASS
63
+ char * external
64
+ char * system
65
+ ALIAS:
66
+ parse_uri = 1
67
+ PREINIT:
68
+ xmlDtdPtr dtd = NULL;
69
+ CODE:
70
+ LibXML_error = sv_2mortal(newSVpv("", 0));
71
+ dtd = xmlParseDTD((const xmlChar*)external, (const xmlChar*)system);
72
+ if ( dtd == NULL ) {
73
+ XSRETURN_UNDEF;
74
+ }
75
+ xmlSetTreeDoc((xmlNodePtr)dtd, NULL);
76
+ RETVAL = PmmNodeToSv( (xmlNodePtr) dtd, NULL );
77
+ OUTPUT:
78
+ RETVAL
79
+ */
80
+
81
+ case 1:
82
+
83
+ rb_scan_args(argc, argv, "10", &dtd_string);
84
+ buffer = xmlAllocParserInputBuffer(enc);
85
+ //if ( !buffer) return Qnil
86
+ new_string = xmlStrdup((xmlChar*)StringValuePtr(dtd_string));
87
+ xmlParserInputBufferPush(buffer, xmlStrlen(new_string), (const char*)new_string);
88
+
89
+ rxdtd = ALLOC(ruby_xml_dtd);
90
+ rxdtd->dtd = xmlIOParseDTD(NULL, buffer, enc);
91
+
92
+ // NOTE: For some reason freeing this InputBuffer causes a segfault!
93
+ // xmlFreeParserInputBuffer(buffer);
94
+ xmlFree(new_string);
95
+
96
+ return( Data_Wrap_Struct(cXMLDtd, ruby_xml_dtd_mark, ruby_xml_dtd_free, rxdtd) );
97
+
98
+ break;
99
+ /*
100
+ SV * parse_string(CLASS, str, ...)
101
+ char * CLASS
102
+ char * str
103
+ PREINIT:
104
+ STRLEN n_a;
105
+ xmlDtdPtr res;
106
+ SV * encoding_sv;
107
+ xmlParserInputBufferPtr buffer;
108
+ xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
109
+ xmlChar * new_string;
110
+ STRLEN len;
111
+ CODE:
112
+ LibXML_init_error();
113
+ if (items > 2) {
114
+ encoding_sv = ST(2);
115
+ if (items > 3) {
116
+ croak("parse_string: too many parameters");
117
+ }
118
+ // warn("getting encoding...\n");
119
+ enc = xmlParseCharEncoding(SvPV(encoding_sv, n_a));
120
+ if (enc == XML_CHAR_ENCODING_ERROR) {
121
+ croak("Parse of encoding %s failed: %s", SvPV(encoding_sv, n_a), SvPV(LibXML_error, n_a));
122
+ }
123
+ }
124
+ buffer = xmlAllocParserInputBuffer(enc);
125
+ // buffer = xmlParserInputBufferCreateMem(str, xmlStrlen(str), enc);
126
+ if ( !buffer)
127
+ croak("cant create buffer!\n" );
128
+
129
+ new_string = xmlStrdup((const xmlChar*)str);
130
+ xmlParserInputBufferPush(buffer, xmlStrlen(new_string), (const char*)new_string);
131
+
132
+ res = xmlIOParseDTD(NULL, buffer, enc);
133
+
134
+ // NOTE: For some reason freeing this InputBuffer causes a segfault!
135
+ // xmlFreeParserInputBuffer(buffer);
136
+ xmlFree(new_string);
137
+
138
+ sv_2mortal( LibXML_error );
139
+ LibXML_croak_error();
140
+
141
+ if (res == NULL) {
142
+ croak("no DTD parsed!");
143
+ }
144
+ RETVAL = PmmNodeToSv((xmlNodePtr)res, NULL);
145
+ OUTPUT:
146
+ RETVAL
147
+ */
148
+
149
+ default:
150
+ rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
151
+ }
152
+
153
+ //docobj = ruby_xml_document_new2(cXMLDocument, xmlver);
154
+ return Qnil;
155
+ }
156
+
157
+ // Rdoc needs to know
158
+ #ifdef RDOC_NEVER_DEFINED
159
+ mXML = rb_define_module("XML");
160
+ #endif
161
+
162
+ void
163
+ ruby_init_xml_dtd(void) {
164
+ cXMLDtd = rb_define_class_under(mXML, "Dtd", rb_cObject);
165
+ rb_define_singleton_method(cXMLDtd, "new", ruby_xml_dtd_initialize, -1);
166
+ //rb_define_method(cXMLDocument, "xinclude", ruby_xml_document_xinclude, 0);
167
+ }
168
+
@@ -0,0 +1,17 @@
1
+ #ifndef __RUBY_XML_DTD__
2
+ #define __RUBY_XML_DTD__
3
+
4
+ extern VALUE cXMLDtd;
5
+
6
+ typedef struct rxp_dtd {
7
+ xmlDtdPtr dtd; /* DTD interface */
8
+ //int data_type; /* The data type referenced by *data */
9
+ //void *data; /* Pointer to an external structure of options */
10
+ //int is_ptr; /* Determines if this object owns its data or points to it someplace else */
11
+ //VALUE xmlver; /* T_STRING with the xml version */
12
+ } ruby_xml_dtd;
13
+
14
+ void ruby_init_xml_dtd(void);
15
+ void ruby_dtd_free(ruby_xml_dtd *rxdtd);
16
+
17
+ #endif
@@ -0,0 +1,167 @@
1
+
2
+ /* ruby support for custom scheme handlers */
3
+ /* Author: Martin Povolny (xpovolny@fi.muni.cz) */
4
+
5
+ #include "libxml.h"
6
+ #include "ruby_xml_input_cbg.h"
7
+
8
+ static ic_scheme *first_scheme = 0;
9
+
10
+ int ic_match (char const *filename) {
11
+ ic_scheme *scheme;
12
+
13
+ //fprintf( stderr, "ic_match: %s\n", filename );
14
+
15
+ scheme = first_scheme;
16
+ while (0 != scheme) {
17
+ if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST scheme->scheme_name, scheme->name_len)) {
18
+ return 1;
19
+ }
20
+ scheme = scheme->next_scheme;
21
+ }
22
+ return 0;
23
+ }
24
+
25
+ void* ic_open (char const *filename) {
26
+ ic_doc_context *ic_doc;
27
+ ic_scheme *scheme;
28
+ VALUE res;
29
+
30
+ scheme = first_scheme;
31
+ while (0 != scheme) {
32
+ if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST scheme->scheme_name, scheme->name_len)) {
33
+ ic_doc = (ic_doc_context*)malloc( sizeof(ic_doc_context) );
34
+
35
+ // MUFF res = rb_funcall(
36
+ // rb_funcall( rb_mKernel,
37
+ // rb_intern("const_get"), 1,
38
+ // rb_str_new2(scheme->class) ),
39
+ // rb_intern("document_query"), 1, rb_str_new2(filename) );
40
+ res = rb_funcall( scheme->class,
41
+ rb_intern("document_query"),
42
+ 1,
43
+ rb_str_new2(filename) );
44
+
45
+ ic_doc->buffer = strdup( StringValuePtr(res) );
46
+
47
+ ic_doc->bpos = ic_doc->buffer;
48
+ ic_doc->remaining = strlen(ic_doc->buffer);
49
+ return ic_doc;
50
+ }
51
+ scheme = scheme->next_scheme;
52
+ }
53
+ return 0;
54
+ }
55
+
56
+ int ic_read (void *context, char *buffer, int len) {
57
+ ic_doc_context *ic_doc;
58
+ int ret_len;
59
+ ic_doc = (ic_doc_context*)context;
60
+
61
+ if (len >= ic_doc->remaining) {
62
+ ret_len = ic_doc->remaining;
63
+ } else {
64
+ ret_len = len;
65
+ }
66
+ ic_doc->remaining -= ret_len;
67
+ strncpy( buffer, ic_doc->bpos, ret_len );
68
+ ic_doc->bpos += ret_len;
69
+
70
+ return ret_len;
71
+ }
72
+
73
+ int ic_close (void *context) {
74
+ free( ((ic_doc_context*)context)->buffer );
75
+ free( context );
76
+ return 1;
77
+ }
78
+
79
+ VALUE input_callbacks_register_input_callbacks() {
80
+ xmlRegisterInputCallbacks( ic_match, ic_open, ic_read, ic_close );
81
+ return(Qtrue);
82
+ }
83
+
84
+ VALUE
85
+ input_callbacks_add_scheme (VALUE self, VALUE scheme_name, VALUE class) {
86
+ ic_scheme *scheme;
87
+
88
+ Check_Type(scheme_name, T_STRING);
89
+ //MUFF Check_Type(class, T_STRING);
90
+
91
+ scheme = (ic_scheme*)malloc(sizeof(ic_scheme));
92
+ scheme->next_scheme = 0;
93
+ scheme->scheme_name = strdup(StringValuePtr(scheme_name)); /* TODO alloc, dealloc */
94
+ scheme->name_len = strlen(scheme->scheme_name);
95
+ //MUFF scheme->class = strdup(StringValuePtr(class)); /* TODO alloc, dealloc */
96
+ scheme->class = class; /* TODO alloc, dealloc */
97
+
98
+ //fprintf( stderr, "registered: %s, %d, %s\n", scheme->scheme_name, scheme->name_len, scheme->class );
99
+
100
+ if (0 == first_scheme)
101
+ first_scheme = scheme;
102
+ else {
103
+ ic_scheme *pos;
104
+ pos = first_scheme;
105
+ while (0 != pos->next_scheme)
106
+ pos = pos->next_scheme;
107
+ pos->next_scheme = scheme;
108
+ }
109
+
110
+ return(Qtrue);
111
+ }
112
+
113
+ VALUE
114
+ input_callbacks_remove_scheme (VALUE self, VALUE scheme_name) {
115
+ char *name;
116
+ ic_scheme *save_scheme, *scheme;
117
+
118
+ Check_Type(scheme_name, T_STRING);
119
+ name = StringValuePtr(scheme_name);
120
+
121
+ if (0 == first_scheme)
122
+ return Qfalse;
123
+
124
+ /* check the first one */
125
+ if (!strncmp(name, first_scheme->scheme_name, first_scheme->name_len)) {
126
+ save_scheme = first_scheme->next_scheme;
127
+
128
+ free(first_scheme->scheme_name);
129
+ //MUFF free(first_scheme->class);
130
+ free(first_scheme);
131
+
132
+ first_scheme = save_scheme;
133
+ return Qtrue;
134
+ }
135
+
136
+ scheme = first_scheme;
137
+ while (0 != scheme->next_scheme) {
138
+ if ( !strncmp( name, scheme->next_scheme->scheme_name, scheme->next_scheme->name_len ) ) {
139
+ save_scheme = scheme->next_scheme->next_scheme;
140
+
141
+ free(scheme->next_scheme->scheme_name);
142
+ //MUFF free(scheme->next_scheme->class);
143
+ free(scheme->next_scheme);
144
+
145
+ scheme->next_scheme = save_scheme;
146
+ return Qtrue;
147
+ }
148
+ scheme = scheme->next_scheme;
149
+ }
150
+ return Qfalse;
151
+ }
152
+
153
+ // Rdoc needs to know
154
+ #ifdef RDOC_NEVER_DEFINED
155
+ mXML = rb_define_module("XML");
156
+ #endif
157
+
158
+ void
159
+ ruby_init_input_callbacks(void) {
160
+ VALUE cInputCallbacks;
161
+ cInputCallbacks = rb_define_class_under(mXML, "InputCallbacks", rb_cObject);
162
+
163
+ /* Class Methods */
164
+ rb_define_singleton_method(cInputCallbacks, "register", input_callbacks_register_input_callbacks, 0);
165
+ rb_define_singleton_method(cInputCallbacks, "add_scheme", input_callbacks_add_scheme, 2);
166
+ rb_define_singleton_method(cInputCallbacks, "remove_scheme", input_callbacks_remove_scheme, 1);
167
+ }
@@ -0,0 +1,21 @@
1
+ #ifndef _INPUT_CBG_
2
+ #define _INPUT_CBG_
3
+
4
+ void ruby_init_input_callbacks(void);
5
+
6
+ typedef struct ic_doc_context {
7
+ char *buffer;
8
+ char *bpos;
9
+ int remaining;
10
+ } ic_doc_context;
11
+
12
+ typedef struct ic_scheme {
13
+ char *scheme_name;
14
+ //MUFF char *class;
15
+ VALUE class;
16
+ int name_len;
17
+
18
+ struct ic_scheme *next_scheme;
19
+ } ic_scheme;
20
+
21
+ #endif
@@ -0,0 +1,2052 @@
1
+ /* $Id: ruby_xml_node.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_node.h"
7
+
8
+ VALUE cXMLNode;
9
+ VALUE eXMLNodeSetNamespace;
10
+ VALUE eXMLNodeFailedModify;
11
+ VALUE eXMLNodeUnknownType;
12
+
13
+ /*
14
+ * call-seq:
15
+ * node.attribute? => (true|false)
16
+ *
17
+ * Determine whether this is an attribute node,
18
+ */
19
+ VALUE
20
+ ruby_xml_node_attribute_q(VALUE self) {
21
+ ruby_xml_node *rxn;
22
+ Data_Get_Struct(self, ruby_xml_node, rxn);
23
+ if (rxn->node->type == XML_ATTRIBUTE_NODE)
24
+ return(Qtrue);
25
+ else
26
+ return(Qfalse);
27
+ }
28
+
29
+
30
+ /*
31
+ * call-seq:
32
+ * node.attribute_decl? => (true|false)
33
+ *
34
+ * Determine whether this is an attribute declaration node,
35
+ */
36
+ VALUE
37
+ ruby_xml_node_attribute_decl_q(VALUE self) {
38
+ ruby_xml_node *rxn;
39
+ Data_Get_Struct(self, ruby_xml_node, rxn);
40
+ if (rxn->node->type == XML_ATTRIBUTE_DECL)
41
+ return(Qtrue);
42
+ else
43
+ return(Qfalse);
44
+ }
45
+
46
+
47
+ /*
48
+ * call-seq:
49
+ * node.base => "uri"
50
+ *
51
+ * Obtain this node's base URI.
52
+ */
53
+ VALUE
54
+ ruby_xml_node_base_get(VALUE self) {
55
+ ruby_xml_node *rxn;
56
+ Data_Get_Struct(self, ruby_xml_node, rxn);
57
+ if (rxn->node->doc == NULL)
58
+ return(Qnil);
59
+
60
+ // TODO some NULL checking, raises ArgumentError in Ruby:
61
+ // ArgumentError: NULL pointer given
62
+
63
+ return(rb_str_new2((const char*)xmlNodeGetBase(rxn->node->doc, rxn->node)));
64
+ }
65
+
66
+
67
+ // TODO node_base_set should support setting back to nil
68
+
69
+ /*
70
+ * call-seq:
71
+ * node.base = "uri"
72
+ *
73
+ * Set this node's base URI.
74
+ */
75
+ VALUE
76
+ ruby_xml_node_base_set(VALUE self, VALUE uri) {
77
+ ruby_xml_node *node;
78
+
79
+ Check_Type(uri, T_STRING);
80
+ Data_Get_Struct(self, ruby_xml_node, node);
81
+ if (node->node->doc == NULL)
82
+ return(Qnil);
83
+
84
+ xmlNodeSetBase(node->node, (xmlChar*)StringValuePtr(uri));
85
+ return(Qtrue);
86
+ }
87
+
88
+
89
+ /*
90
+ * call-seq:
91
+ * node.cdata? => (true|false)
92
+ *
93
+ * Determine whether this is a #CDATA node
94
+ */
95
+ VALUE
96
+ ruby_xml_node_cdata_q(VALUE self) {
97
+ ruby_xml_node *rxn;
98
+ Data_Get_Struct(self, ruby_xml_node, rxn);
99
+ if (rxn->node->type == XML_CDATA_SECTION_NODE)
100
+ return(Qtrue);
101
+ else
102
+ return(Qfalse);
103
+ }
104
+
105
+
106
+ /*
107
+ * call-seq:
108
+ * node.comment? => (true|false)
109
+ *
110
+ * Determine whether this is a comment node
111
+ */
112
+ VALUE
113
+ ruby_xml_node_comment_q(VALUE self) {
114
+ ruby_xml_node *rxn;
115
+ Data_Get_Struct(self, ruby_xml_node, rxn);
116
+ if (rxn->node->type == XML_COMMENT_NODE)
117
+ return(Qtrue);
118
+ else
119
+ return(Qfalse);
120
+ }
121
+
122
+
123
+ /*
124
+ * call-seq:
125
+ * node << ("string" | node)
126
+ *
127
+ * Add the specified string or XML::Node to this node's
128
+ * content.
129
+ */
130
+ VALUE
131
+ ruby_xml_node_content_add(VALUE self, VALUE obj) {
132
+ ruby_xml_node *node;
133
+ VALUE str;
134
+
135
+ Data_Get_Struct(self, ruby_xml_node, node);
136
+ if (rb_obj_is_kind_of(obj, cXMLNode)) {
137
+ return(ruby_xml_node_child_set(self, obj));
138
+ } else if (TYPE(obj) == T_STRING) {
139
+ xmlNodeAddContent(node->node, (xmlChar*)StringValuePtr(obj));
140
+ return(obj);
141
+ } else {
142
+ str = rb_obj_as_string(obj);
143
+ if (NIL_P(str) || TYPE(str) != T_STRING)
144
+ rb_raise(rb_eTypeError, "invalid argumnt: must be string or XML::Node");
145
+
146
+ xmlNodeAddContent(node->node, (xmlChar*)StringValuePtr(str));
147
+ return(obj);
148
+ }
149
+ }
150
+
151
+
152
+ /*
153
+ * call-seq:
154
+ * node.content => "string"
155
+ *
156
+ * Obtain this node's content as a string.
157
+ */
158
+ VALUE
159
+ ruby_xml_node_content_get(VALUE self) {
160
+ ruby_xml_node *rxn;
161
+
162
+ Data_Get_Struct(self, ruby_xml_node, rxn);
163
+ if (rxn->node->type == XML_ELEMENT_NODE || rxn->node->content == NULL)
164
+ return(Qnil);
165
+ else {
166
+ return(rb_str_new2((const char*)rxn->node->content));
167
+ }
168
+ }
169
+
170
+ /////////////////////////////////////////////
171
+ // TODO may be bugged:
172
+ //
173
+ // node.content = "123"
174
+ // node.content => nil
175
+ // node.content_stripped => nil
176
+ // node.to_s => "<head xml:base=\"123\">wow</head>"
177
+
178
+
179
+ /*
180
+ * call-seq:
181
+ * node.content = "string"
182
+ *
183
+ * Set this node's content to the specified string.
184
+ */
185
+ VALUE
186
+ ruby_xml_node_content_set(VALUE self, VALUE content) {
187
+ ruby_xml_node *node;
188
+
189
+ Check_Type(content, T_STRING);
190
+ Data_Get_Struct(self, ruby_xml_node, node);
191
+ xmlNodeSetContent(node->node, (xmlChar*)StringValuePtr(content));
192
+ return(Qtrue);
193
+ }
194
+
195
+
196
+ /////////////////////////////////////////////////////
197
+ // TODO may be bugged: see above
198
+ //
199
+
200
+ /*
201
+ * call-seq:
202
+ * node.content_stripped => "string"
203
+ *
204
+ * Obtain this node's stripped content.
205
+ */
206
+ VALUE
207
+ ruby_xml_node_content_stripped_get(VALUE self) {
208
+ ruby_xml_node *rxn;
209
+
210
+ Data_Get_Struct(self, ruby_xml_node, rxn);
211
+ if (rxn->node->content == NULL)
212
+ return(Qnil);
213
+ else
214
+ return(rb_str_new2((const char*)xmlNodeGetContent(rxn->node)));
215
+ }
216
+
217
+ ////////////////////////////////////////////////////
218
+ // TODO This whole child thing seems to work in some odd ways.
219
+ // Try setting child= to a node with multiple children,
220
+ // then get it back through child= .
221
+
222
+ /*
223
+ * call-seq:
224
+ * node.child => node
225
+ *
226
+ * Obtain this node's first child node, if any.
227
+ */
228
+ VALUE
229
+ ruby_xml_node_child_get(VALUE self) {
230
+ ruby_xml_node *node;
231
+ xmlNodePtr tmp;
232
+
233
+ Data_Get_Struct(self, ruby_xml_node, node);
234
+
235
+ switch (node->node->type) {
236
+ case XML_ELEMENT_NODE:
237
+ case XML_ENTITY_REF_NODE:
238
+ case XML_ENTITY_NODE:
239
+ case XML_PI_NODE:
240
+ case XML_COMMENT_NODE:
241
+ case XML_DOCUMENT_NODE:
242
+ #ifdef LIBXML_DOCB_ENABLED
243
+ case XML_DOCB_DOCUMENT_NODE:
244
+ #endif
245
+ case XML_HTML_DOCUMENT_NODE:
246
+ case XML_DTD_NODE:
247
+ tmp = node->node->children;
248
+ break;
249
+ case XML_ATTRIBUTE_NODE:
250
+ {
251
+ xmlAttrPtr attr = (xmlAttrPtr) node->node;
252
+ tmp = attr->children;
253
+ break;
254
+ }
255
+ default:
256
+ tmp = NULL;
257
+ break;
258
+ }
259
+
260
+ if (tmp == NULL)
261
+ return(Qnil);
262
+ else
263
+ return(ruby_xml_node_new2(cXMLNode, node->xd, tmp));
264
+ }
265
+
266
+
267
+ /*
268
+ * call-seq:
269
+ * node.child? => (true|false)
270
+ *
271
+ * Determine whether this node has at least one child.
272
+ */
273
+ VALUE
274
+ ruby_xml_node_child_q(VALUE self) {
275
+ ruby_xml_node *rxn;
276
+ xmlNodePtr node;
277
+ Data_Get_Struct(self, ruby_xml_node, rxn);
278
+
279
+ node = NULL;
280
+ switch (rxn->node->type) {
281
+ case XML_ELEMENT_NODE:
282
+ case XML_ENTITY_REF_NODE:
283
+ case XML_ENTITY_NODE:
284
+ case XML_PI_NODE:
285
+ case XML_COMMENT_NODE:
286
+ case XML_DOCUMENT_NODE:
287
+ #ifdef LIBXML_DOCB_ENABLED
288
+ case XML_DOCB_DOCUMENT_NODE:
289
+ #endif
290
+ case XML_HTML_DOCUMENT_NODE:
291
+ case XML_DTD_NODE:
292
+ node = rxn->node->children;
293
+ break;
294
+ case XML_ATTRIBUTE_NODE:
295
+ {
296
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
297
+ node = attr->children;
298
+ break;
299
+ }
300
+ default:
301
+ node = NULL;
302
+ }
303
+
304
+ if (node == NULL)
305
+ return(Qfalse);
306
+ else
307
+ return(Qtrue);
308
+ }
309
+
310
+
311
+ /*
312
+ * call-seq:
313
+ * node.child = node
314
+ *
315
+ * Set a child node for this node.
316
+ */
317
+ VALUE
318
+ ruby_xml_node_child_set(VALUE self, VALUE rnode) {
319
+ ruby_xml_node *cnode, *pnode;
320
+ xmlNodePtr ret;
321
+
322
+ if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
323
+ rb_raise(rb_eTypeError, "Must pass an XML::Node object");
324
+
325
+ Data_Get_Struct(self, ruby_xml_node, pnode);
326
+ Data_Get_Struct(rnode, ruby_xml_node, cnode);
327
+
328
+ ret = xmlAddChild(pnode->node, cnode->node);
329
+ if (ret == NULL)
330
+ rb_raise(eXMLNodeFailedModify, "unable to add a child to the document");
331
+
332
+ ruby_xml_node_set_ptr(rnode, 1);
333
+ return(ruby_xml_node_new2(cXMLNode, pnode->xd, ret));
334
+ }
335
+
336
+ ////////////////////////////////////////////////
337
+ // TODO new Documents seem to be created quite readily...
338
+
339
+ /*
340
+ * call-seq:
341
+ * node.doc => document
342
+ *
343
+ * Obtain the XML::Document this node belongs to.
344
+ */
345
+ VALUE
346
+ ruby_xml_node_doc(VALUE self) {
347
+ ruby_xml_document *rxd;
348
+ ruby_xml_node *rxn;
349
+ xmlDocPtr doc;
350
+ VALUE docobj;
351
+
352
+ Data_Get_Struct(self, ruby_xml_node, rxn);
353
+
354
+ switch (rxn->node->type) {
355
+ case XML_DOCUMENT_NODE:
356
+ #ifdef LIBXML_DOCB_ENABLED
357
+ case XML_DOCB_DOCUMENT_NODE:
358
+ #endif
359
+ case XML_HTML_DOCUMENT_NODE:
360
+ doc = NULL;
361
+ break;
362
+ case XML_ATTRIBUTE_NODE:
363
+ {
364
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
365
+ doc = attr->doc;
366
+ break;
367
+ }
368
+ case XML_NAMESPACE_DECL:
369
+ doc = NULL;
370
+ break;
371
+ default:
372
+ doc = rxn->node->doc;
373
+ break;
374
+ }
375
+
376
+ if (doc == NULL)
377
+ return(Qnil);
378
+
379
+ docobj = ruby_xml_document_new(cXMLDocument, doc);
380
+ Data_Get_Struct(docobj, ruby_xml_document, rxd);
381
+ rxd->is_ptr = 1;
382
+ return(docobj);
383
+ }
384
+
385
+
386
+ /*
387
+ * call-seq:
388
+ * node.docbook? => (true|false)
389
+ *
390
+ * Determine whether this is a docbook node.
391
+ */
392
+ VALUE
393
+ ruby_xml_node_docbook_doc_q(VALUE self) {
394
+ #ifdef LIBXML_DOCB_ENABLED
395
+ ruby_xml_node *rxn;
396
+ Data_Get_Struct(self, ruby_xml_node, rxn);
397
+ if (rxn->node->type == XML_DOCB_DOCUMENT_NODE)
398
+ return(Qtrue);
399
+ else
400
+ return(Qfalse);
401
+ #else
402
+ rb_warn("libxml compiled without docbook support");
403
+ return(Qfalse);
404
+ #endif
405
+ }
406
+
407
+
408
+ /*
409
+ * call-seq:
410
+ * node.doctype? => (true|false)
411
+ *
412
+ * Determine whether this is a DOCTYPE node.
413
+ */
414
+ VALUE
415
+ ruby_xml_node_doctype_q(VALUE self) {
416
+ ruby_xml_node *rxn;
417
+ Data_Get_Struct(self, ruby_xml_node, rxn);
418
+ if (rxn->node->type == XML_DOCUMENT_TYPE_NODE)
419
+ return(Qtrue);
420
+ else
421
+ return(Qfalse);
422
+ }
423
+
424
+
425
+ /*
426
+ * call-seq:
427
+ * node.document? => (true|false)
428
+ *
429
+ * Determine whether this is a document node.
430
+ */
431
+ VALUE
432
+ ruby_xml_node_document_q(VALUE self) {
433
+ ruby_xml_node *rxn;
434
+ Data_Get_Struct(self, ruby_xml_node, rxn);
435
+ if (rxn->node->type == XML_DOCUMENT_NODE)
436
+ return(Qtrue);
437
+ else
438
+ return(Qfalse);
439
+ }
440
+
441
+
442
+ /*
443
+ * call-seq:
444
+ * node.dtd? => (true|false)
445
+ *
446
+ * Determine whether this is a DTD node.
447
+ */
448
+ VALUE
449
+ ruby_xml_node_dtd_q(VALUE self) {
450
+ ruby_xml_node *rxn;
451
+ Data_Get_Struct(self, ruby_xml_node, rxn);
452
+ if (rxn->node->type == XML_DTD_NODE)
453
+ return(Qtrue);
454
+ else
455
+ return(Qfalse);
456
+ }
457
+
458
+
459
+ /*
460
+ * call-seq:
461
+ * node.dump => (true|nil)
462
+ *
463
+ * Dump this node to stdout.
464
+ */
465
+ VALUE
466
+ ruby_xml_node_dump(VALUE self) {
467
+ ruby_xml_node *rxn;
468
+ xmlBufferPtr buf;
469
+
470
+ Data_Get_Struct(self, ruby_xml_node, rxn);
471
+
472
+ if (rxn->node->doc == NULL)
473
+ return(Qnil);
474
+
475
+ buf = xmlBufferCreate();
476
+ xmlNodeDump(buf, rxn->node->doc, rxn->node, 0, 1);
477
+ xmlBufferDump(stdout, buf);
478
+ xmlBufferFree(buf);
479
+ return(Qtrue);
480
+ }
481
+
482
+
483
+ /*
484
+ * call-seq:
485
+ * node.debug_dump => (true|nil)
486
+ *
487
+ * Dump this node to stdout, including any debugging
488
+ * information.
489
+ */
490
+ VALUE
491
+ ruby_xml_node_debug_dump(VALUE self) {
492
+ ruby_xml_node *rxn;
493
+ Data_Get_Struct(self, ruby_xml_node, rxn);
494
+
495
+ if (rxn->node->doc == NULL)
496
+ return(Qnil);
497
+
498
+ xmlElemDump(stdout, rxn->node->doc, rxn->node);
499
+ return(Qtrue);
500
+ }
501
+
502
+
503
+ /*
504
+ * call-seq:
505
+ * node.element? => (true|false)
506
+ *
507
+ * Determine whether this is an element node.
508
+ */
509
+ VALUE
510
+ ruby_xml_node_element_q(VALUE self) {
511
+ ruby_xml_node *rxn;
512
+ Data_Get_Struct(self, ruby_xml_node, rxn);
513
+ if (rxn->node->type == XML_ELEMENT_NODE)
514
+ return(Qtrue);
515
+ else
516
+ return(Qfalse);
517
+ }
518
+
519
+
520
+ /*
521
+ * call-seq:
522
+ * node.element_decl? => (true|false)
523
+ *
524
+ * Determine whether this is an element declaration node.
525
+ */
526
+ VALUE
527
+ ruby_xml_node_element_decl_q(VALUE self) {
528
+ ruby_xml_node *rxn;
529
+ Data_Get_Struct(self, ruby_xml_node, rxn);
530
+ if (rxn->node->type == XML_ELEMENT_DECL)
531
+ return(Qtrue);
532
+ else
533
+ return(Qfalse);
534
+ }
535
+
536
+
537
+ /*
538
+ * call-seq:
539
+ * node.empty? => (true|false)
540
+ *
541
+ * Determine whether this node is empty.
542
+ */
543
+ VALUE
544
+ ruby_xml_node_empty_q(VALUE self) {
545
+ ruby_xml_node *rxn;
546
+ Data_Get_Struct(self, ruby_xml_node, rxn);
547
+ if (rxn->node == NULL)
548
+ return(Qnil);
549
+
550
+ return((xmlIsBlankNode(rxn->node) == 1) ? Qtrue : Qfalse);
551
+ }
552
+
553
+
554
+ /*
555
+ * call-seq:
556
+ * node.entity? => (true|false)
557
+ *
558
+ * Determine whether this is an entity node.
559
+ */
560
+ VALUE
561
+ ruby_xml_node_entity_q(VALUE self) {
562
+ ruby_xml_node *rxn;
563
+ Data_Get_Struct(self, ruby_xml_node, rxn);
564
+ if (rxn->node->type == XML_ENTITY_NODE)
565
+ return(Qtrue);
566
+ else
567
+ return(Qfalse);
568
+ }
569
+
570
+
571
+ /*
572
+ * call-seq:
573
+ * node.entity_ref? => (true|false)
574
+ *
575
+ * Determine whether this is an entity reference node.
576
+ */
577
+ VALUE
578
+ ruby_xml_node_entity_ref_q(VALUE self) {
579
+ ruby_xml_node *rxn;
580
+ Data_Get_Struct(self, ruby_xml_node, rxn);
581
+ if (rxn->node->type == XML_ENTITY_REF_NODE)
582
+ return(Qtrue);
583
+ else
584
+ return(Qfalse);
585
+ }
586
+
587
+
588
+ /*
589
+ * call-seq:
590
+ * node.find(xpath_expr, namespace = [any]) => nodeset
591
+ *
592
+ * Find nodes matching the specified xpath expression, optionally
593
+ * using the specified namespaces. Returns an XML::Node::Set.
594
+ */
595
+ VALUE
596
+ ruby_xml_node_find(int argc, VALUE *argv, VALUE self) {
597
+ int i, vargc;
598
+ VALUE *vargv;
599
+
600
+ if (argc > 2 || argc < 1)
601
+ rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
602
+
603
+ vargc = argc + 1;
604
+ vargv = ALLOC_N(VALUE, vargc + 1);
605
+ vargv[0] = self;
606
+ for (i = 0; i<argc; i++)
607
+ vargv[i + 1] = argv[i];
608
+
609
+ return(ruby_xml_xpath_find2(vargc, vargv));
610
+ }
611
+
612
+
613
+ /*
614
+ * call-seq:
615
+ * node.fragment? => (true|false)
616
+ *
617
+ * Determine whether this node is a fragment.
618
+ */
619
+ VALUE
620
+ ruby_xml_node_fragment_q(VALUE self) {
621
+ ruby_xml_node *rxn;
622
+ Data_Get_Struct(self, ruby_xml_node, rxn);
623
+ if (rxn->node->type == XML_DOCUMENT_FRAG_NODE)
624
+ return(Qtrue);
625
+ else
626
+ return(Qfalse);
627
+ }
628
+
629
+
630
+ void ruby_xml_node_free(ruby_xml_node *rxn) {
631
+ if (rxn->node != NULL && !rxn->is_ptr) {
632
+ xmlUnlinkNode(rxn->node);
633
+ xmlFreeNode(rxn->node);
634
+ rxn->node = NULL;
635
+ }
636
+
637
+ free(rxn);
638
+ }
639
+
640
+
641
+ /*
642
+ * call-seq:
643
+ * node.html_doc? => (true|false)
644
+ *
645
+ * Determine whether this node is an html document node.
646
+ */
647
+ VALUE
648
+ ruby_xml_node_html_doc_q(VALUE self) {
649
+ ruby_xml_node *rxn;
650
+ Data_Get_Struct(self, ruby_xml_node, rxn);
651
+ if (rxn->node->type == XML_HTML_DOCUMENT_NODE)
652
+ return(Qtrue);
653
+ else
654
+ return(Qfalse);
655
+ }
656
+
657
+
658
+ /*
659
+ * call-seq:
660
+ * XML::Node.new(name, content = nil) => node
661
+ *
662
+ * Create a new node with the specified name, optionally setting
663
+ * the node's content.
664
+ */
665
+ VALUE
666
+ ruby_xml_node_initialize(int argc, VALUE *argv, VALUE class) {
667
+ ruby_xml_node *rxn;
668
+ VALUE name, node, str;
669
+
670
+ str = Qnil;
671
+
672
+ switch(argc) {
673
+ case 2:
674
+ switch (TYPE(str)) {
675
+ case T_STRING:
676
+ str = argv[1];
677
+ break;
678
+ default:
679
+ str = rb_obj_as_string(argv[1]);
680
+ if (NIL_P(str))
681
+ Check_Type(str, T_STRING);
682
+ break;
683
+ }
684
+
685
+ /* Intentionally fall through to case 1: as a way of setting up
686
+ * the object. Sneaky, but effective. Probably should use a goto
687
+ * instead. */
688
+ case 1:
689
+ name = argv[0];
690
+ Check_Type(name, T_STRING);
691
+ node = ruby_xml_node_new(class, NULL);
692
+ Data_Get_Struct(node, ruby_xml_node, rxn);
693
+ rxn->node = xmlNewNode(NULL, (xmlChar*)StringValuePtr(name));
694
+ if (rxn->node == NULL)
695
+ return(Qnil);
696
+
697
+ if (!NIL_P(str))
698
+ ruby_xml_node_content_set(node, str);
699
+
700
+ break;
701
+
702
+ default:
703
+ rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
704
+ }
705
+
706
+ return(node);
707
+ }
708
+
709
+
710
+ /*
711
+ * call-seq:
712
+ * node.lang => "string"
713
+ *
714
+ * Obtain the language set for this node, if any.
715
+ * This is set in XML via the xml:lang attribute.
716
+ */
717
+ VALUE
718
+ ruby_xml_node_lang_get(VALUE self) {
719
+ ruby_xml_node *rxn;
720
+ xmlChar *lang;
721
+
722
+ Data_Get_Struct(self, ruby_xml_node, rxn);
723
+ lang = xmlNodeGetLang(rxn->node);
724
+
725
+ if (lang == NULL)
726
+ return(Qnil);
727
+ else
728
+ return(rb_str_new2((const char*)lang));
729
+ }
730
+
731
+
732
+ // TODO node_lang_set should support setting back to nil
733
+
734
+ /*
735
+ * call-seq:
736
+ * node.lang = "string"
737
+ *
738
+ * Set the language for this node. This affects the value
739
+ * of the xml:lang attribute.
740
+ */
741
+ VALUE
742
+ ruby_xml_node_lang_set(VALUE self, VALUE lang) {
743
+ ruby_xml_node *node;
744
+
745
+ Check_Type(lang, T_STRING);
746
+ Data_Get_Struct(self, ruby_xml_node, node);
747
+ xmlNodeSetLang(node->node, (xmlChar*)StringValuePtr(lang));
748
+
749
+ return(Qtrue);
750
+ }
751
+
752
+
753
+ /*
754
+ * call-seq:
755
+ * node.last => node
756
+ *
757
+ * Obtain the last child node of this node, if any.
758
+ */
759
+ VALUE
760
+ ruby_xml_node_last_get(VALUE self) {
761
+ ruby_xml_node *rxn;
762
+ xmlNodePtr node;
763
+
764
+ Data_Get_Struct(self, ruby_xml_node, rxn);
765
+
766
+ switch (rxn->node->type) {
767
+ case XML_ELEMENT_NODE:
768
+ case XML_ENTITY_REF_NODE:
769
+ case XML_ENTITY_NODE:
770
+ case XML_PI_NODE:
771
+ case XML_COMMENT_NODE:
772
+ case XML_DOCUMENT_NODE:
773
+ #ifdef LIBXML_DOCB_ENABLED
774
+ case XML_DOCB_DOCUMENT_NODE:
775
+ #endif
776
+ case XML_HTML_DOCUMENT_NODE:
777
+ case XML_DTD_NODE:
778
+ node = rxn->node->last;
779
+ break;
780
+ case XML_ATTRIBUTE_NODE:
781
+ {
782
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
783
+ node = attr->last;
784
+ }
785
+ default:
786
+ node = NULL;
787
+ break;
788
+ }
789
+
790
+ if (node == NULL)
791
+ return(Qnil);
792
+ else
793
+ return(ruby_xml_node_new2(cXMLNode, rxn->xd, node));
794
+ }
795
+
796
+
797
+ /*
798
+ * call-seq:
799
+ * node.last? => (true|false)
800
+ *
801
+ * Determine whether this node has a last child node.
802
+ */
803
+ VALUE
804
+ ruby_xml_node_last_q(VALUE self) {
805
+ ruby_xml_node *rxn;
806
+ xmlNodePtr node;
807
+
808
+ Data_Get_Struct(self, ruby_xml_node, rxn);
809
+
810
+ switch (rxn->node->type) {
811
+ case XML_ELEMENT_NODE:
812
+ case XML_ENTITY_REF_NODE:
813
+ case XML_ENTITY_NODE:
814
+ case XML_PI_NODE:
815
+ case XML_COMMENT_NODE:
816
+ case XML_DOCUMENT_NODE:
817
+ #ifdef LIBXML_DOCB_ENABLED
818
+ case XML_DOCB_DOCUMENT_NODE:
819
+ #endif
820
+ case XML_HTML_DOCUMENT_NODE:
821
+ case XML_DTD_NODE:
822
+ node = rxn->node->last;
823
+ break;
824
+ case XML_ATTRIBUTE_NODE:
825
+ {
826
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
827
+ node = attr->last;
828
+ }
829
+ default:
830
+ node = NULL;
831
+ break;
832
+ }
833
+
834
+ if (node == NULL)
835
+ return(Qfalse);
836
+ else
837
+ return(Qtrue);
838
+ }
839
+
840
+
841
+ /*
842
+ * call-seq:
843
+ * node.line_num => num
844
+ *
845
+ * Obtain the line number (in the XML document) that this
846
+ * node was read from. If +default_line_numbers+ is set
847
+ * false (the default), this method returns zero.
848
+ */
849
+ VALUE
850
+ ruby_xml_node_line_num(VALUE self) {
851
+ ruby_xml_node *rxn;
852
+ long line_num;
853
+ Data_Get_Struct(self, ruby_xml_node, rxn);
854
+
855
+ if (!xmlLineNumbersDefaultValue)
856
+ rb_warn("Line numbers were not retained: use XML::Parser::default_line_numbers=true");
857
+
858
+ line_num = xmlGetLineNo(rxn->node);
859
+ if (line_num == -1)
860
+ return(Qnil);
861
+ else
862
+ return(INT2NUM((long)line_num));
863
+ }
864
+
865
+
866
+ /*
867
+ * call-seq:
868
+ * node.xlink? => (true|false)
869
+ *
870
+ * Determine whether this node is an xlink node.
871
+ */
872
+ VALUE
873
+ ruby_xml_node_xlink_q(VALUE self) {
874
+ ruby_xml_node *node;
875
+ ruby_xml_document *doc;
876
+ xlinkType xlt;
877
+
878
+ Data_Get_Struct(self, ruby_xml_node, node);
879
+ Data_Get_Struct(node->xd, ruby_xml_document, doc);
880
+ xlt = xlinkIsLink(doc->doc, node->node);
881
+
882
+ if (xlt == XLINK_TYPE_NONE)
883
+ return(Qfalse);
884
+ else
885
+ return(Qtrue);
886
+ }
887
+
888
+
889
+ /*
890
+ * call-seq:
891
+ * node.xlink_type => num
892
+ *
893
+ * Obtain the type identifier for this xlink, if applicable.
894
+ * If this is not an xlink node (see +xlink?+), will return
895
+ * nil.
896
+ */
897
+ VALUE
898
+ ruby_xml_node_xlink_type(VALUE self) {
899
+ ruby_xml_node *node;
900
+ ruby_xml_document *doc;
901
+ xlinkType xlt;
902
+
903
+ Data_Get_Struct(self, ruby_xml_node, node);
904
+ Data_Get_Struct(node->xd, ruby_xml_document, doc);
905
+ xlt = xlinkIsLink(doc->doc, node->node);
906
+
907
+ if (xlt == XLINK_TYPE_NONE)
908
+ return(Qnil);
909
+ else
910
+ return(INT2NUM(xlt));
911
+ }
912
+
913
+
914
+ /*
915
+ * call-seq:
916
+ * node.xlink_type_name => "string"
917
+ *
918
+ * Obtain the type name for this xlink, if applicable.
919
+ * If this is not an xlink node (see +xlink?+), will return
920
+ * nil.
921
+ */
922
+ VALUE
923
+ ruby_xml_node_xlink_type_name(VALUE self) {
924
+ ruby_xml_node *node;
925
+ ruby_xml_document *doc;
926
+ xlinkType xlt;
927
+
928
+ Data_Get_Struct(self, ruby_xml_node, node);
929
+ Data_Get_Struct(node->xd, ruby_xml_document, doc);
930
+ xlt = xlinkIsLink(doc->doc, node->node);
931
+
932
+ switch(xlt) {
933
+ case XLINK_TYPE_NONE:
934
+ return(Qnil);
935
+ case XLINK_TYPE_SIMPLE:
936
+ return(rb_str_new2("simple"));
937
+ case XLINK_TYPE_EXTENDED:
938
+ return(rb_str_new2("extended"));
939
+ case XLINK_TYPE_EXTENDED_SET:
940
+ return(rb_str_new2("extended_set"));
941
+ default:
942
+ rb_fatal("Unknowng xlink type, %d", xlt);
943
+ }
944
+ }
945
+
946
+
947
+ static void
948
+ ruby_xml_node_mark(ruby_xml_node *rxn) {
949
+ if (rxn == NULL) return;
950
+ if (!NIL_P(rxn->xd)) rb_gc_mark(rxn->xd);
951
+ }
952
+
953
+
954
+ /*
955
+ * call-seq:
956
+ * node.name => "string"
957
+ *
958
+ * Obtain this node's name.
959
+ */
960
+ VALUE
961
+ ruby_xml_node_name_get(VALUE self) {
962
+ ruby_xml_node *rxn;
963
+ const xmlChar *name;
964
+
965
+ Data_Get_Struct(self, ruby_xml_node, rxn);
966
+
967
+ switch (rxn->node->type) {
968
+ case XML_DOCUMENT_NODE:
969
+ #ifdef LIBXML_DOCB_ENABLED
970
+ case XML_DOCB_DOCUMENT_NODE:
971
+ #endif
972
+ case XML_HTML_DOCUMENT_NODE:
973
+ {
974
+ xmlDocPtr doc = (xmlDocPtr) rxn->node;
975
+ name = doc->URL;
976
+ break;
977
+ }
978
+ case XML_ATTRIBUTE_NODE:
979
+ {
980
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
981
+ name = attr->name;
982
+ break;
983
+ }
984
+ case XML_NAMESPACE_DECL:
985
+ {
986
+ xmlNsPtr ns = (xmlNsPtr) rxn->node;
987
+ name = ns->prefix;
988
+ break;
989
+ }
990
+ default:
991
+ name = rxn->node->name;
992
+ break;
993
+ }
994
+
995
+ if (rxn->node->name == NULL)
996
+ return(Qnil);
997
+ else
998
+ return(rb_str_new2((const char*)name));
999
+ }
1000
+
1001
+
1002
+ /*
1003
+ * call-seq:
1004
+ * node.name = "string"
1005
+ *
1006
+ * Set this node's name.
1007
+ */
1008
+ VALUE
1009
+ ruby_xml_node_name_set(VALUE self, VALUE name) {
1010
+ ruby_xml_node *node;
1011
+
1012
+ Check_Type(name, T_STRING);
1013
+ Data_Get_Struct(self, ruby_xml_node, node);
1014
+ xmlNodeSetName(node->node, (xmlChar*)StringValuePtr(name));
1015
+ return(Qtrue);
1016
+ }
1017
+
1018
+
1019
+ /*
1020
+ * call-seq:
1021
+ * node.namespace => [namespace, ..., namespace]
1022
+ *
1023
+ * Obtain an array of +XML::NS+ objects representing
1024
+ * this node's xmlns attributes
1025
+ */
1026
+ VALUE
1027
+ ruby_xml_node_namespace_get(VALUE self) {
1028
+ ruby_xml_node *node;
1029
+ xmlNsPtr *nsList, *cur;
1030
+ VALUE arr, ns;
1031
+
1032
+ Data_Get_Struct(self, ruby_xml_node, node);
1033
+ if (node->node == NULL)
1034
+ return(Qnil);
1035
+
1036
+ nsList = xmlGetNsList(node->node->doc, node->node);
1037
+
1038
+ if (nsList == NULL)
1039
+ return(Qnil);
1040
+
1041
+ arr = rb_ary_new();
1042
+ for (cur = nsList; *cur != NULL; cur++) {
1043
+ ns = ruby_xml_ns_new2(cXMLNS, node->xd, *cur);
1044
+ if (ns == Qnil)
1045
+ continue;
1046
+ else
1047
+ rb_ary_push(arr, ns);
1048
+ }
1049
+ xmlFree(nsList);
1050
+
1051
+ return(arr);
1052
+ }
1053
+
1054
+
1055
+ /*
1056
+ * call-seq:
1057
+ * node.namespace_node => namespace.
1058
+ *
1059
+ * Obtain this node's namespace node.
1060
+ */
1061
+ VALUE
1062
+ ruby_xml_node_namespace_get_node(VALUE self) {
1063
+ ruby_xml_node *node;
1064
+
1065
+ Data_Get_Struct(self, ruby_xml_node, node);
1066
+ if (node->node->ns == NULL)
1067
+ return(Qnil);
1068
+ else
1069
+ return(ruby_xml_ns_new2(cXMLNS, node->xd, node->node->ns));
1070
+ }
1071
+
1072
+ // TODO namespace_set can take varargs (in fact, must if used
1073
+ // with strings), but I cannot see how you can call
1074
+ // that version, apart from with 'send'
1075
+ //
1076
+ // Would sure be nice to support foo.namespace['foo'] = 'bar'
1077
+ // but maybe that's not practical...
1078
+
1079
+ /*
1080
+ * call-seq:
1081
+ * node.namespace = namespace
1082
+ *
1083
+ * Add the specified XML::NS object to this node's xmlns attributes.
1084
+ */
1085
+ VALUE
1086
+ ruby_xml_node_namespace_set(int argc, VALUE *argv, VALUE self) {
1087
+ VALUE rns, rprefix;
1088
+ ruby_xml_node *rxn;
1089
+ ruby_xml_ns *rxns;
1090
+ xmlNsPtr ns;
1091
+ char *cp, *href;
1092
+
1093
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1094
+ switch (argc) {
1095
+ case 1:
1096
+ rns = argv[0];
1097
+ if (TYPE(rns) == T_STRING) {
1098
+ cp = strchr(StringValuePtr(rns), (int)':');
1099
+ if (cp == NULL) {
1100
+ rprefix = rns;
1101
+ href = NULL;
1102
+ } else {
1103
+ rprefix = rb_str_new(StringValuePtr(rns), (int)((long)cp - (long)StringValuePtr(rns)));
1104
+ href = &cp[1]; /* skip the : */
1105
+ }
1106
+ } else if (rb_obj_is_kind_of(rns, cXMLNS) == Qtrue) {
1107
+ Data_Get_Struct(self, ruby_xml_ns, rxns);
1108
+ xmlSetNs(rxn->node, rxns->ns);
1109
+ return(rns);
1110
+ } else
1111
+ rb_raise(rb_eTypeError, "must pass a string or an XML::Ns object");
1112
+
1113
+ /* Fall through to next case because when argc == 1, we need to
1114
+ * manually setup the additional args unless the arg passed is of
1115
+ * cXMLNS type */
1116
+ case 2:
1117
+ /* Don't want this code run in the fall through case */
1118
+ if (argc == 2) {
1119
+ rprefix = argv[0];
1120
+ href = StringValuePtr(argv[1]);
1121
+ }
1122
+
1123
+ ns = xmlNewNs(rxn->node, (xmlChar*)href, (xmlChar*)StringValuePtr(rprefix));
1124
+ if (ns == NULL)
1125
+ rb_raise(eXMLNodeSetNamespace, "unable to set the namespace");
1126
+ else
1127
+ return(ruby_xml_ns_new2(cXMLNS, rxn->xd, ns));
1128
+ break;
1129
+
1130
+ default:
1131
+ rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
1132
+ }
1133
+
1134
+ /* can't get here */
1135
+ return(Qnil);
1136
+ }
1137
+
1138
+
1139
+ /*
1140
+ * call-seq:
1141
+ * node.namespace? => (true|false)
1142
+ *
1143
+ * Determine whether this node *is* (not has) a namespace
1144
+ * node.
1145
+ */
1146
+ VALUE
1147
+ ruby_xml_node_namespace_q(VALUE self) {
1148
+ ruby_xml_node *rxn;
1149
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1150
+ if (rxn->node->type == XML_NAMESPACE_DECL)
1151
+ return(Qtrue);
1152
+ else
1153
+ return(Qfalse);
1154
+ }
1155
+
1156
+
1157
+ VALUE
1158
+ ruby_xml_node_new(VALUE class, xmlNodePtr node) {
1159
+ ruby_xml_node *rxn;
1160
+
1161
+ rxn = ALLOC(ruby_xml_node);
1162
+ rxn->is_ptr = 0;
1163
+ rxn->node = node;
1164
+ rxn->xd = Qnil;
1165
+ return(Data_Wrap_Struct(class, ruby_xml_node_mark,
1166
+ ruby_xml_node_free, rxn));
1167
+ }
1168
+
1169
+
1170
+ VALUE
1171
+ ruby_xml_node_new2(VALUE class, VALUE xd, xmlNodePtr node) {
1172
+ ruby_xml_node *rxn;
1173
+
1174
+ rxn = ALLOC(ruby_xml_node);
1175
+ rxn->is_ptr = 1;
1176
+ rxn->node = node;
1177
+ if (NIL_P(xd))
1178
+ rxn->xd = Qnil;
1179
+ else
1180
+ rxn->xd = xd;
1181
+ return(Data_Wrap_Struct(class, ruby_xml_node_mark,
1182
+ ruby_xml_node_free, rxn));
1183
+ }
1184
+
1185
+
1186
+ /*
1187
+ * call-seq:
1188
+ * node.next => node
1189
+ *
1190
+ * Obtain the next sibling node, if any.
1191
+ */
1192
+ VALUE
1193
+ ruby_xml_node_next_get(VALUE self) {
1194
+ ruby_xml_node *rxn;
1195
+ xmlNodePtr node;
1196
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1197
+
1198
+ switch (rxn->node->type) {
1199
+ case XML_DOCUMENT_NODE:
1200
+ #ifdef LIBXML_DOCB_ENABLED
1201
+ case XML_DOCB_DOCUMENT_NODE:
1202
+ #endif
1203
+ case XML_HTML_DOCUMENT_NODE:
1204
+ node = NULL;
1205
+ break;
1206
+ case XML_ATTRIBUTE_NODE:
1207
+ {
1208
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1209
+ node = (xmlNodePtr) attr->next;
1210
+ break;
1211
+ }
1212
+ case XML_NAMESPACE_DECL:
1213
+ {
1214
+ xmlNsPtr ns = (xmlNsPtr) rxn->node;
1215
+ node = (xmlNodePtr) ns->next;
1216
+ break;
1217
+ }
1218
+ default:
1219
+ node = rxn->node->next;
1220
+ break;
1221
+ }
1222
+
1223
+ if (node == NULL)
1224
+ return(Qnil);
1225
+ else
1226
+ return(ruby_xml_node_new2(cXMLNode, rxn->xd, node));
1227
+ }
1228
+
1229
+
1230
+ /*
1231
+ * call-seq:
1232
+ * node.next? => (true|false)
1233
+ *
1234
+ * Determine whether this node has a next sibling.
1235
+ */
1236
+ VALUE
1237
+ ruby_xml_node_next_q(VALUE self) {
1238
+ ruby_xml_node *rxn;
1239
+ xmlNodePtr node;
1240
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1241
+
1242
+ switch (rxn->node->type) {
1243
+ case XML_DOCUMENT_NODE:
1244
+ #ifdef LIBXML_DOCB_ENABLED
1245
+ case XML_DOCB_DOCUMENT_NODE:
1246
+ #endif
1247
+ case XML_HTML_DOCUMENT_NODE:
1248
+ node = NULL;
1249
+ break;
1250
+ case XML_ATTRIBUTE_NODE:
1251
+ {
1252
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1253
+ node = (xmlNodePtr) attr->next;
1254
+ break;
1255
+ }
1256
+ case XML_NAMESPACE_DECL:
1257
+ {
1258
+ xmlNsPtr ns = (xmlNsPtr) rxn->node;
1259
+ node = (xmlNodePtr) ns->next;
1260
+ break;
1261
+ }
1262
+ default:
1263
+ node = rxn->node->next;
1264
+ break;
1265
+ }
1266
+
1267
+ if (node == NULL)
1268
+ return(Qfalse);
1269
+ else
1270
+ return(Qtrue);
1271
+ }
1272
+
1273
+
1274
+ /*
1275
+ * call-seq:
1276
+ * node.notation? => (true|false)
1277
+ *
1278
+ * Determine whether this is a notation node
1279
+ */
1280
+ VALUE
1281
+ ruby_xml_node_notation_q(VALUE self) {
1282
+ ruby_xml_node *rxn;
1283
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1284
+ if (rxn->node->type == XML_NOTATION_NODE)
1285
+ return(Qtrue);
1286
+ else
1287
+ return(Qfalse);
1288
+ }
1289
+
1290
+
1291
+ /*
1292
+ * call-seq:
1293
+ * node.ns? => (true|false)
1294
+ *
1295
+ * Determine whether this node is a namespace node.
1296
+ */
1297
+ VALUE
1298
+ ruby_xml_node_ns_q(VALUE self) {
1299
+ ruby_xml_node *rxn;
1300
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1301
+ if (rxn->node->ns == NULL)
1302
+ return(Qfalse);
1303
+ else
1304
+ return(Qtrue);
1305
+ }
1306
+
1307
+
1308
+ /*
1309
+ * call-seq:
1310
+ * node.ns_def => namespace
1311
+ *
1312
+ * Obtain this node's default namespace.
1313
+ */
1314
+ VALUE
1315
+ ruby_xml_node_ns_def_get(VALUE self) {
1316
+ ruby_xml_node *rxn;
1317
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1318
+ if (rxn->node->nsDef == NULL)
1319
+ return(Qnil);
1320
+ else
1321
+ return(ruby_xml_ns_new2(cXMLNS, rxn->xd, rxn->node->nsDef));
1322
+ }
1323
+
1324
+
1325
+ /*
1326
+ * call-seq:
1327
+ * node.ns_def? => (true|false)
1328
+ *
1329
+ * Obtain an array of +XML::NS+ objects representing
1330
+ * this node's xmlns attributes
1331
+ */
1332
+ VALUE
1333
+ ruby_xml_node_ns_def_q(VALUE self) {
1334
+ ruby_xml_node *rxn;
1335
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1336
+ if (rxn->node->nsDef == NULL)
1337
+ return(Qfalse);
1338
+ else
1339
+ return(Qtrue);
1340
+ }
1341
+
1342
+
1343
+ /*
1344
+ * call-seq:
1345
+ * node.parent => node
1346
+ *
1347
+ * Obtain this node's parent node, if any.
1348
+ */
1349
+ VALUE
1350
+ ruby_xml_node_parent_get(VALUE self) {
1351
+ ruby_xml_node *rxn;
1352
+ xmlNodePtr node;
1353
+
1354
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1355
+
1356
+ switch (rxn->node->type) {
1357
+ case XML_DOCUMENT_NODE:
1358
+ case XML_HTML_DOCUMENT_NODE:
1359
+ #ifdef LIBXML_DOCB_ENABLED
1360
+ case XML_DOCB_DOCUMENT_NODE:
1361
+ #endif
1362
+ node = NULL;
1363
+ break;
1364
+ case XML_ATTRIBUTE_NODE:
1365
+ {
1366
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1367
+ node = attr->parent;
1368
+ }
1369
+ case XML_ENTITY_DECL:
1370
+ case XML_NAMESPACE_DECL:
1371
+ case XML_XINCLUDE_START:
1372
+ case XML_XINCLUDE_END:
1373
+ node = NULL;
1374
+ break;
1375
+ default:
1376
+ node = rxn->node->parent;
1377
+ break;
1378
+ }
1379
+
1380
+ if (node == NULL)
1381
+ return(Qnil);
1382
+ else
1383
+ return(ruby_xml_node_new2(cXMLNode, rxn->xd, node));
1384
+ }
1385
+
1386
+
1387
+ /*
1388
+ * call-seq:
1389
+ * node.parent? => (true|false)
1390
+ *
1391
+ * Determine whether this node has a parent node.
1392
+ */
1393
+ VALUE
1394
+ ruby_xml_node_parent_q(VALUE self) {
1395
+ ruby_xml_node *rxn;
1396
+ xmlNodePtr node;
1397
+
1398
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1399
+
1400
+ switch (rxn->node->type) {
1401
+ case XML_DOCUMENT_NODE:
1402
+ case XML_HTML_DOCUMENT_NODE:
1403
+ #ifdef LIBXML_DOCB_ENABLED
1404
+ case XML_DOCB_DOCUMENT_NODE:
1405
+ #endif
1406
+ node = NULL;
1407
+ break;
1408
+ case XML_ATTRIBUTE_NODE:
1409
+ {
1410
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1411
+ node = attr->parent;
1412
+ }
1413
+ case XML_ENTITY_DECL:
1414
+ case XML_NAMESPACE_DECL:
1415
+ case XML_XINCLUDE_START:
1416
+ case XML_XINCLUDE_END:
1417
+ node = NULL;
1418
+ break;
1419
+ default:
1420
+ node = rxn->node->parent;
1421
+ break;
1422
+ }
1423
+
1424
+ if (node == NULL)
1425
+ return(Qfalse);
1426
+ else
1427
+ return(Qtrue);
1428
+ }
1429
+
1430
+
1431
+ /*
1432
+ * call-seq:
1433
+ * node.path => path
1434
+ *
1435
+ * Obtain this node's path.
1436
+ */
1437
+ VALUE
1438
+ ruby_xml_node_path(VALUE self) {
1439
+ ruby_xml_node *rxn;
1440
+ xmlChar *path;
1441
+
1442
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1443
+ path = xmlGetNodePath(rxn->node);
1444
+
1445
+ if (path == NULL)
1446
+ return(Qnil);
1447
+ else
1448
+ return(rb_str_new2((const char*)path));
1449
+ }
1450
+
1451
+
1452
+ /*
1453
+ * call-seq:
1454
+ * node.pi? => (true|false)
1455
+ *
1456
+ * Determine whether this is a processing instruction node.
1457
+ */
1458
+ VALUE
1459
+ ruby_xml_node_pi_q(VALUE self) {
1460
+ ruby_xml_node *rxn;
1461
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1462
+ if (rxn->node->type == XML_PI_NODE)
1463
+ return(Qtrue);
1464
+ else
1465
+ return(Qfalse);
1466
+ }
1467
+
1468
+
1469
+ /*
1470
+ * call-seq:
1471
+ * node.pointer => node_set
1472
+ *
1473
+ * Evaluates an XPointer expression relative to this node.
1474
+ */
1475
+ VALUE
1476
+ ruby_xml_node_pointer(VALUE self, VALUE xptr_str) {
1477
+ return(ruby_xml_xpointer_point2(self, xptr_str));
1478
+ }
1479
+
1480
+
1481
+ /*
1482
+ * call-seq:
1483
+ * node.prev => node
1484
+ *
1485
+ * Obtain the previous sibling, if any.
1486
+ */
1487
+ VALUE
1488
+ ruby_xml_node_prev_get(VALUE self) {
1489
+ ruby_xml_node *rxn;
1490
+ xmlNodePtr node;
1491
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1492
+
1493
+ switch (rxn->node->type) {
1494
+ case XML_DOCUMENT_NODE:
1495
+ #ifdef LIBXML_DOCB_ENABLED
1496
+ case XML_DOCB_DOCUMENT_NODE:
1497
+ #endif
1498
+ case XML_HTML_DOCUMENT_NODE:
1499
+ case XML_NAMESPACE_DECL:
1500
+ node = NULL;
1501
+ break;
1502
+ case XML_ATTRIBUTE_NODE:
1503
+ {
1504
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1505
+ node = (xmlNodePtr) attr->next;
1506
+ }
1507
+ break;
1508
+ default:
1509
+ node = rxn->node->next;
1510
+ break;
1511
+ }
1512
+
1513
+ if (node == NULL)
1514
+ return(Qnil);
1515
+ else
1516
+ return(ruby_xml_node_new2(cXMLNode, rxn->xd, node));
1517
+ }
1518
+
1519
+
1520
+ /*
1521
+ * call-seq:
1522
+ * node.prev? => (true|false)
1523
+ *
1524
+ * Determines whether this node has a previous sibling node.
1525
+ */
1526
+ VALUE
1527
+ ruby_xml_node_prev_q(VALUE self) {
1528
+ ruby_xml_node *rxn;
1529
+ xmlNodePtr node;
1530
+
1531
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1532
+
1533
+ switch (rxn->node->type) {
1534
+ case XML_DOCUMENT_NODE:
1535
+ #ifdef LIBXML_DOCB_ENABLED
1536
+ case XML_DOCB_DOCUMENT_NODE:
1537
+ #endif
1538
+ case XML_HTML_DOCUMENT_NODE:
1539
+ case XML_NAMESPACE_DECL:
1540
+ node = NULL;
1541
+ break;
1542
+ case XML_ATTRIBUTE_NODE:
1543
+ {
1544
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1545
+ node = (xmlNodePtr) attr->next;
1546
+ }
1547
+ break;
1548
+ default:
1549
+ node = rxn->node->next;
1550
+ break;
1551
+ }
1552
+
1553
+ if (node == NULL)
1554
+ return(Qfalse);
1555
+ else
1556
+ return(Qtrue);
1557
+ }
1558
+
1559
+
1560
+ /*
1561
+ * call-seq:
1562
+ * node.property("name") => "string"
1563
+ * node["name"] => "string"
1564
+ *
1565
+ * Obtain the named property.
1566
+ */
1567
+ VALUE
1568
+ ruby_xml_node_property_get(VALUE self, VALUE prop) {
1569
+ ruby_xml_node *rxn;
1570
+ xmlChar *p;
1571
+ VALUE r;
1572
+
1573
+ Check_Type(prop, T_STRING);
1574
+
1575
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1576
+ p = xmlGetProp(rxn->node, (xmlChar*)StringValuePtr(prop));
1577
+
1578
+ if (p == NULL)
1579
+ r = Qnil;
1580
+ else {
1581
+ r = rb_str_new2((const char*)p);
1582
+ xmlFree(p);
1583
+ }
1584
+
1585
+ return r;
1586
+ }
1587
+
1588
+
1589
+ /*
1590
+ * call-seq:
1591
+ * node["name"] = "string"
1592
+ *
1593
+ * Set the named property.
1594
+ */
1595
+ VALUE
1596
+ ruby_xml_node_property_set(VALUE self, VALUE key, VALUE val) {
1597
+ ruby_xml_node *node;
1598
+ ruby_xml_attr *rxa;
1599
+ xmlAttrPtr attr;
1600
+ VALUE rattr;
1601
+
1602
+ Check_Type(key, T_STRING);
1603
+ Check_Type(val, T_STRING);
1604
+ Data_Get_Struct(self, ruby_xml_node, node);
1605
+
1606
+ attr = xmlSetProp(node->node, (xmlChar*)StringValuePtr(key), (xmlChar*)StringValuePtr(val));
1607
+ if (attr == NULL) {
1608
+ attr = xmlNewProp(node->node, (xmlChar*)StringValuePtr(key), (xmlChar*)StringValuePtr(val));
1609
+ if (attr == NULL)
1610
+ return(Qnil);
1611
+ }
1612
+ rattr = ruby_xml_attr_new(cXMLAttr, node->xd, attr);
1613
+ Data_Get_Struct(rattr, ruby_xml_attr, rxa);
1614
+ rxa->is_ptr = 1;
1615
+ return(rattr);
1616
+ }
1617
+
1618
+
1619
+ /*
1620
+ * call-seq:
1621
+ * node.properties => attributes
1622
+ *
1623
+ * Returns the +XML::Attr+ for this node.
1624
+ */
1625
+ VALUE
1626
+ ruby_xml_node_properties_get(VALUE self) {
1627
+ ruby_xml_node *node;
1628
+ xmlAttrPtr attr;
1629
+
1630
+ Data_Get_Struct(self, ruby_xml_node, node);
1631
+
1632
+ if (node->node->type == XML_ELEMENT_NODE) {
1633
+ attr = node->node->properties;
1634
+ return(ruby_xml_attr_new2(cXMLAttr, node->xd, attr));
1635
+ } else {
1636
+ return(Qnil);
1637
+ }
1638
+ }
1639
+
1640
+
1641
+ /*
1642
+ * call-seq:
1643
+ * node.properties? => (true|false)
1644
+ *
1645
+ * Determine whether this node has properties
1646
+ * (attributes).
1647
+ */
1648
+ VALUE
1649
+ ruby_xml_node_properties_q(VALUE self) {
1650
+ ruby_xml_node *rxn;
1651
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1652
+ if (rxn->node->type == XML_ELEMENT_NODE && rxn->node->properties != NULL)
1653
+ return(Qtrue);
1654
+ else
1655
+ return(Qfalse);
1656
+ }
1657
+
1658
+
1659
+ /*
1660
+ * call-seq:
1661
+ * node.search_href => namespace
1662
+ *
1663
+ * Search for a namespace by href.
1664
+ */
1665
+ VALUE
1666
+ ruby_xml_node_search_href(VALUE self, VALUE href) {
1667
+ ruby_xml_document *doc;
1668
+ ruby_xml_node *node;
1669
+
1670
+ Check_Type(href, T_STRING);
1671
+ Data_Get_Struct(self, ruby_xml_node, node);
1672
+ Data_Get_Struct(node->xd, ruby_xml_document, doc);
1673
+ return(ruby_xml_ns_new2(cXMLNS, node->xd,
1674
+ xmlSearchNsByHref(doc->doc, node->node,
1675
+ (xmlChar*)StringValuePtr(href))));
1676
+ }
1677
+
1678
+
1679
+ /*
1680
+ * call-seq:
1681
+ * node.search_ns => namespace
1682
+ *
1683
+ * Search for a namespace by namespace.
1684
+ */
1685
+ VALUE
1686
+ ruby_xml_node_search_ns(VALUE self, VALUE ns) {
1687
+ ruby_xml_document *doc;
1688
+ ruby_xml_node *node;
1689
+
1690
+ Check_Type(ns, T_STRING);
1691
+ Data_Get_Struct(self, ruby_xml_node, node);
1692
+ Data_Get_Struct(node->xd, ruby_xml_document, doc);
1693
+ return(ruby_xml_ns_new2(cXMLNS, node->xd,
1694
+ xmlSearchNs(doc->doc, node->node,
1695
+ (xmlChar*)StringValuePtr(ns))));
1696
+ }
1697
+
1698
+
1699
+ VALUE
1700
+ ruby_xml_node_set_ptr(VALUE node, int is_ptr) {
1701
+ ruby_xml_node *rxn;
1702
+ Data_Get_Struct(node, ruby_xml_node, rxn);
1703
+ rxn->is_ptr = is_ptr;
1704
+ return(Qtrue);
1705
+ }
1706
+
1707
+
1708
+ /*
1709
+ * call-seq:
1710
+ * node.sibling(node) => node
1711
+ *
1712
+ * Add the specified node as a sibling of this node.
1713
+ */
1714
+ VALUE
1715
+ ruby_xml_node_sibling_set(VALUE self, VALUE rnode) {
1716
+ ruby_xml_node *cnode, *pnode;
1717
+ xmlNodePtr ret;
1718
+
1719
+ if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
1720
+ rb_raise(rb_eTypeError, "Must pass an XML::Node object");
1721
+
1722
+ Data_Get_Struct(self, ruby_xml_node, pnode);
1723
+ Data_Get_Struct(rnode, ruby_xml_node, cnode);
1724
+
1725
+ ret = xmlAddSibling(pnode->node, cnode->node);
1726
+ if (ret == NULL)
1727
+ rb_raise(eXMLNodeFailedModify, "unable to add a sibling to the document");
1728
+
1729
+ cnode->is_ptr = 1;
1730
+ return(ruby_xml_node_new2(cXMLNode, pnode->xd, ret));
1731
+ }
1732
+
1733
+
1734
+ /*
1735
+ * call-seq:
1736
+ * node.space_preserve => (true|false)
1737
+ *
1738
+ * Determine whether this node preserves whitespace.
1739
+ */
1740
+ VALUE
1741
+ ruby_xml_node_space_preserve_get(VALUE self) {
1742
+ ruby_xml_node *rxn;
1743
+
1744
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1745
+ return(INT2NUM(xmlNodeGetSpacePreserve(rxn->node)));
1746
+ }
1747
+
1748
+
1749
+ /*
1750
+ * call-seq:
1751
+ * node.space_preserve = true|false
1752
+ *
1753
+ * Control whether this node preserves whitespace.
1754
+ */
1755
+ VALUE
1756
+ ruby_xml_node_space_preserve_set(VALUE self, VALUE bool) {
1757
+ ruby_xml_node *rxn;
1758
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1759
+
1760
+ if (TYPE(bool) == T_FALSE)
1761
+ xmlNodeSetSpacePreserve(rxn->node, 1);
1762
+ else
1763
+ xmlNodeSetSpacePreserve(rxn->node, 0);
1764
+
1765
+ return(Qnil);
1766
+ }
1767
+
1768
+
1769
+ /*
1770
+ * call-seq:
1771
+ * node.text? => (true|false)
1772
+ *
1773
+ * Determine whether this node has text.
1774
+ */
1775
+ VALUE
1776
+ ruby_xml_node_text_q(VALUE self) {
1777
+ ruby_xml_node *rxn;
1778
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1779
+ if (rxn->node == NULL)
1780
+ return(Qnil);
1781
+
1782
+ return((xmlNodeIsText(rxn->node) == 1) ? Qtrue : Qfalse);
1783
+ }
1784
+
1785
+
1786
+ /*
1787
+ * call-seq:
1788
+ * node.to_s => "string"
1789
+ *
1790
+ * Coerce this node to a string representation of
1791
+ * it's XML.
1792
+ */
1793
+ VALUE
1794
+ ruby_xml_node_to_s(VALUE self) {
1795
+ ruby_xml_node *rxn;
1796
+ xmlBufferPtr buf;
1797
+ VALUE result;
1798
+
1799
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1800
+ buf = xmlBufferCreate();
1801
+ xmlNodeDump(buf, rxn->node->doc, rxn->node, 0, 1);
1802
+ result = rb_str_new2((const char*)buf->content);
1803
+ // TODO result = rb_str_new2((const char*)buf->content); ?
1804
+
1805
+ xmlBufferFree(buf);
1806
+ return result;
1807
+ }
1808
+
1809
+
1810
+ /*
1811
+ * call-seq:
1812
+ * node.type => num
1813
+ *
1814
+ * Obtain this node's type identifier.
1815
+ */
1816
+ VALUE
1817
+ ruby_xml_node_type(VALUE self) {
1818
+ ruby_xml_node *rxn;
1819
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1820
+ return(INT2NUM(rxn->node->type));
1821
+ }
1822
+
1823
+
1824
+ /*
1825
+ * call-seq:
1826
+ * node.type_name => num
1827
+ *
1828
+ * Obtain this node's type name.
1829
+ */
1830
+ VALUE
1831
+ ruby_xml_node_type_name(VALUE self) {
1832
+ ruby_xml_node *rxn;
1833
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1834
+
1835
+ switch(rxn->node->type) {
1836
+ case XML_ELEMENT_NODE:
1837
+ return(rb_str_new2("element"));
1838
+ case XML_ATTRIBUTE_NODE:
1839
+ return(rb_str_new2("attribute"));
1840
+ case XML_TEXT_NODE:
1841
+ return(rb_str_new2("text"));
1842
+ case XML_CDATA_SECTION_NODE:
1843
+ return(rb_str_new2("cdata"));
1844
+ case XML_ENTITY_REF_NODE:
1845
+ return(rb_str_new2("entity_ref"));
1846
+ case XML_ENTITY_NODE:
1847
+ return(rb_str_new2("entity"));
1848
+ case XML_PI_NODE:
1849
+ return(rb_str_new2("pi"));
1850
+ case XML_COMMENT_NODE:
1851
+ return(rb_str_new2("comment"));
1852
+ case XML_DOCUMENT_NODE:
1853
+ return(rb_str_new2("document_xml"));
1854
+ case XML_DOCUMENT_TYPE_NODE:
1855
+ return(rb_str_new2("doctype"));
1856
+ case XML_DOCUMENT_FRAG_NODE:
1857
+ return(rb_str_new2("fragment"));
1858
+ case XML_NOTATION_NODE:
1859
+ return(rb_str_new2("notation"));
1860
+ case XML_HTML_DOCUMENT_NODE:
1861
+ return(rb_str_new2("document_html"));
1862
+ case XML_DTD_NODE:
1863
+ return(rb_str_new2("dtd"));
1864
+ case XML_ELEMENT_DECL:
1865
+ return(rb_str_new2("elem_decl"));
1866
+ case XML_ATTRIBUTE_DECL:
1867
+ return(rb_str_new2("attribute_decl"));
1868
+ case XML_ENTITY_DECL:
1869
+ return(rb_str_new2("entity_decl"));
1870
+ case XML_NAMESPACE_DECL:
1871
+ return(rb_str_new2("namespace"));
1872
+ case XML_XINCLUDE_START:
1873
+ return(rb_str_new2("xinclude_start"));
1874
+ case XML_XINCLUDE_END:
1875
+ return(rb_str_new2("xinclude_end"));
1876
+ #ifdef LIBXML_DOCB_ENABLED
1877
+ case XML_DOCB_DOCUMENT_NODE:
1878
+ return(rb_str_new2("document_docbook"));
1879
+ #endif
1880
+ default:
1881
+ rb_raise(eXMLNodeUnknownType, "Unknown node type: %n", rxn->node->type);
1882
+ return(Qfalse);
1883
+ }
1884
+ }
1885
+
1886
+
1887
+ /*
1888
+ * call-seq:
1889
+ * node.xinclude_end? => num
1890
+ *
1891
+ * Determine whether this node is an xinclude end node.
1892
+ */
1893
+ VALUE
1894
+ ruby_xml_node_xinclude_end_q(VALUE self) {
1895
+ ruby_xml_node *rxn;
1896
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1897
+ if (rxn->node->type == XML_XINCLUDE_END)
1898
+ return(Qtrue);
1899
+ else
1900
+ return(Qfalse);
1901
+ }
1902
+
1903
+
1904
+ /*
1905
+ * call-seq:
1906
+ * node.xinclude_start? => num
1907
+ *
1908
+ * Determine whether this node is an xinclude start node.
1909
+ */
1910
+ VALUE
1911
+ ruby_xml_node_xinclude_start_q(VALUE self) {
1912
+ ruby_xml_node *rxn;
1913
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1914
+ if (rxn->node->type == XML_XINCLUDE_START)
1915
+ return(Qtrue);
1916
+ else
1917
+ return(Qfalse);
1918
+ }
1919
+
1920
+
1921
+ // TODO my gut tells me this is where our sigseg etc. problems start...
1922
+
1923
+ /*
1924
+ * call-seq:
1925
+ * node.copy => node
1926
+ *
1927
+ * Create a copy of this node.
1928
+ */
1929
+ VALUE
1930
+ ruby_xml_node_copy(VALUE self, VALUE deep) { /* MUFF */
1931
+ ruby_xml_node *rxn, *n_rxn;
1932
+ VALUE n_node;
1933
+
1934
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1935
+
1936
+ n_node = ruby_xml_node_new(cXMLNode, NULL); // class??
1937
+ Data_Get_Struct(n_node, ruby_xml_node, n_rxn);
1938
+
1939
+ n_rxn->node = xmlCopyNode( rxn->node, ((deep==Qnil)||(deep==Qfalse))?0:1 );
1940
+ if (rxn->node == NULL)
1941
+ return(Qnil);
1942
+
1943
+ return n_node;
1944
+ }
1945
+
1946
+
1947
+ // Rdoc needs to know
1948
+ #ifdef RDOC_NEVER_DEFINED
1949
+ mXML = rb_define_module("XML");
1950
+ #endif
1951
+
1952
+ void
1953
+ ruby_init_xml_node(void) {
1954
+ cXMLNode = rb_define_class_under(mXML, "Node", rb_cObject);
1955
+ eXMLNodeSetNamespace = rb_define_class_under(cXMLNode, "SetNamespace", rb_eException);
1956
+ eXMLNodeFailedModify = rb_define_class_under(cXMLNode, "FailedModify", rb_eException);
1957
+ eXMLNodeUnknownType = rb_define_class_under(cXMLNode, "UnknownType", rb_eException);
1958
+
1959
+ rb_define_const(cXMLNode, "SPACE_DEFAULT", INT2NUM(0));
1960
+ rb_define_const(cXMLNode, "SPACE_PRESERVE", INT2NUM(1));
1961
+ rb_define_const(cXMLNode, "SPACE_NOT_INHERIT", INT2NUM(-1));
1962
+ rb_define_const(cXMLNode, "XLINK_ACTUATE_AUTO", INT2NUM(1));
1963
+ rb_define_const(cXMLNode, "XLINK_ACTUATE_NONE", INT2NUM(0));
1964
+ rb_define_const(cXMLNode, "XLINK_ACTUATE_ONREQUEST", INT2NUM(2));
1965
+ rb_define_const(cXMLNode, "XLINK_SHOW_EMBED", INT2NUM(2));
1966
+ rb_define_const(cXMLNode, "XLINK_SHOW_NEW", INT2NUM(1));
1967
+ rb_define_const(cXMLNode, "XLINK_SHOW_NONE", INT2NUM(0));
1968
+ rb_define_const(cXMLNode, "XLINK_SHOW_REPLACE", INT2NUM(3));
1969
+ rb_define_const(cXMLNode, "XLINK_TYPE_EXTENDED", INT2NUM(2));
1970
+ rb_define_const(cXMLNode, "XLINK_TYPE_EXTENDED_SET", INT2NUM(3));
1971
+ rb_define_const(cXMLNode, "XLINK_TYPE_NONE", INT2NUM(0));
1972
+ rb_define_const(cXMLNode, "XLINK_TYPE_SIMPLE", INT2NUM(1));
1973
+
1974
+ rb_define_singleton_method(cXMLNode, "new", ruby_xml_node_initialize, -1);
1975
+
1976
+ rb_define_method(cXMLNode, "<<", ruby_xml_node_content_add, 1);
1977
+ rb_define_method(cXMLNode, "[]", ruby_xml_node_property_get, 1);
1978
+ rb_define_method(cXMLNode, "[]=", ruby_xml_node_property_set, 2);
1979
+ rb_define_method(cXMLNode, "attribute?", ruby_xml_node_attribute_q, 0);
1980
+ rb_define_method(cXMLNode, "attribute_decl?", ruby_xml_node_attribute_decl_q, 0);
1981
+ rb_define_method(cXMLNode, "base", ruby_xml_node_base_get, 0);
1982
+ rb_define_method(cXMLNode, "base=", ruby_xml_node_base_set, 1);
1983
+ rb_define_method(cXMLNode, "blank?", ruby_xml_node_empty_q, 0);
1984
+ rb_define_method(cXMLNode, "cdata?", ruby_xml_node_cdata_q, 0);
1985
+ rb_define_method(cXMLNode, "comment?", ruby_xml_node_comment_q, 0);
1986
+ rb_define_method(cXMLNode, "copy", ruby_xml_node_copy, 1);
1987
+ rb_define_method(cXMLNode, "child", ruby_xml_node_child_get, 0);
1988
+ rb_define_method(cXMLNode, "child?", ruby_xml_node_child_q, 0);
1989
+ rb_define_method(cXMLNode, "child=", ruby_xml_node_child_set, 1);
1990
+ rb_define_method(cXMLNode, "children", ruby_xml_node_child_get, 0);
1991
+ rb_define_method(cXMLNode, "children?", ruby_xml_node_child_q, 0);
1992
+ rb_define_method(cXMLNode, "content", ruby_xml_node_content_get, 0);
1993
+ rb_define_method(cXMLNode, "content=", ruby_xml_node_content_set, 1);
1994
+ rb_define_method(cXMLNode, "content_stripped", ruby_xml_node_content_stripped_get, 0);
1995
+ rb_define_method(cXMLNode, "doc", ruby_xml_node_doc, 0);
1996
+ rb_define_method(cXMLNode, "docbook_doc?", ruby_xml_node_docbook_doc_q, 0);
1997
+ rb_define_method(cXMLNode, "doctype?", ruby_xml_node_doctype_q, 0);
1998
+ rb_define_method(cXMLNode, "document?", ruby_xml_node_document_q, 0);
1999
+ rb_define_method(cXMLNode, "dtd?", ruby_xml_node_dtd_q, 0);
2000
+ rb_define_method(cXMLNode, "dump", ruby_xml_node_dump, 0);
2001
+ rb_define_method(cXMLNode, "debug_dump", ruby_xml_node_debug_dump, 0);
2002
+ rb_define_method(cXMLNode, "element?", ruby_xml_node_element_q, 0);
2003
+ rb_define_method(cXMLNode, "element_decl?", ruby_xml_node_element_decl_q, 0);
2004
+ rb_define_method(cXMLNode, "empty?", ruby_xml_node_empty_q, 0);
2005
+ rb_define_method(cXMLNode, "entity?", ruby_xml_node_entity_q, 0);
2006
+ rb_define_method(cXMLNode, "entity_ref?", ruby_xml_node_entity_ref_q, 0);
2007
+ rb_define_method(cXMLNode, "find", ruby_xml_node_find, -1);
2008
+ rb_define_method(cXMLNode, "fragment?", ruby_xml_node_fragment_q, 0);
2009
+ rb_define_method(cXMLNode, "html_doc?", ruby_xml_node_html_doc_q, 0);
2010
+ rb_define_method(cXMLNode, "lang", ruby_xml_node_lang_get, 0);
2011
+ rb_define_method(cXMLNode, "lang=", ruby_xml_node_lang_set, 1);
2012
+ rb_define_method(cXMLNode, "last", ruby_xml_node_last_get, 0);
2013
+ rb_define_method(cXMLNode, "last?", ruby_xml_node_last_q, 0);
2014
+ rb_define_method(cXMLNode, "line_num", ruby_xml_node_line_num, 0);
2015
+ rb_define_method(cXMLNode, "name", ruby_xml_node_name_get, 0);
2016
+ rb_define_method(cXMLNode, "name=", ruby_xml_node_name_set, 1);
2017
+ rb_define_method(cXMLNode, "namespace", ruby_xml_node_namespace_get, 0);
2018
+ rb_define_method(cXMLNode, "namespace_node", ruby_xml_node_namespace_get_node, 0);
2019
+ rb_define_method(cXMLNode, "namespace?", ruby_xml_node_namespace_q, 0);
2020
+ rb_define_method(cXMLNode, "namespace=", ruby_xml_node_namespace_set, -1);
2021
+ rb_define_method(cXMLNode, "next", ruby_xml_node_next_get, 0);
2022
+ rb_define_method(cXMLNode, "next?", ruby_xml_node_next_q, 0);
2023
+ rb_define_method(cXMLNode, "node_type", ruby_xml_node_type, 0);
2024
+ rb_define_method(cXMLNode, "node_type_name", ruby_xml_node_type_name, 0);
2025
+ rb_define_method(cXMLNode, "notation?", ruby_xml_node_notation_q, 0);
2026
+ rb_define_method(cXMLNode, "ns", ruby_xml_node_namespace_get, 0);
2027
+ rb_define_method(cXMLNode, "ns?", ruby_xml_node_ns_q, 0);
2028
+ rb_define_method(cXMLNode, "ns_def", ruby_xml_node_ns_def_get, 0);
2029
+ rb_define_method(cXMLNode, "ns_def?", ruby_xml_node_ns_def_q, 0);
2030
+ rb_define_method(cXMLNode, "parent", ruby_xml_node_parent_get, 0);
2031
+ rb_define_method(cXMLNode, "parent?", ruby_xml_node_parent_q, 0);
2032
+ rb_define_method(cXMLNode, "path", ruby_xml_node_path, 0);
2033
+ rb_define_method(cXMLNode, "pi?", ruby_xml_node_pi_q, 0);
2034
+ rb_define_method(cXMLNode, "pointer", ruby_xml_node_pointer, 1);
2035
+ rb_define_method(cXMLNode, "prev", ruby_xml_node_prev_get, 0);
2036
+ rb_define_method(cXMLNode, "prev?", ruby_xml_node_prev_q, 0);
2037
+ rb_define_method(cXMLNode, "property", ruby_xml_node_property_get, 1);
2038
+ rb_define_method(cXMLNode, "properties", ruby_xml_node_properties_get, 0);
2039
+ rb_define_method(cXMLNode, "properties?", ruby_xml_node_properties_q, 0);
2040
+ rb_define_method(cXMLNode, "search_ns", ruby_xml_node_search_ns, 1);
2041
+ rb_define_method(cXMLNode, "search_href", ruby_xml_node_search_href, 1);
2042
+ rb_define_method(cXMLNode, "sibling=", ruby_xml_node_sibling_set, 1);
2043
+ rb_define_method(cXMLNode, "space_preserve", ruby_xml_node_space_preserve_get, 0);
2044
+ rb_define_method(cXMLNode, "space_preserve=", ruby_xml_node_space_preserve_set, 1);
2045
+ rb_define_method(cXMLNode, "text?", ruby_xml_node_text_q, 0);
2046
+ rb_define_method(cXMLNode, "to_s", ruby_xml_node_to_s, 0);
2047
+ rb_define_method(cXMLNode, "xinclude_end?", ruby_xml_node_xinclude_end_q, 0);
2048
+ rb_define_method(cXMLNode, "xinclude_start?", ruby_xml_node_xinclude_start_q, 0);
2049
+ rb_define_method(cXMLNode, "xlink?", ruby_xml_node_xlink_q, 0);
2050
+ rb_define_method(cXMLNode, "xlink_type", ruby_xml_node_xlink_type, 0);
2051
+ rb_define_method(cXMLNode, "xlink_type_name", ruby_xml_node_xlink_type_name, 0);
2052
+ }