libxml-ruby 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }