libxml-ruby 0.5.4 → 0.6.0

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 (139) hide show
  1. data/LICENSE +23 -23
  2. data/README +144 -144
  3. data/ext/libxml/extconf.rb +26 -27
  4. data/ext/libxml/libxml.c +7 -37
  5. data/ext/libxml/{libxml.h → ruby_libxml.h} +93 -98
  6. data/ext/libxml/ruby_xml_attr.c +405 -387
  7. data/ext/libxml/ruby_xml_attr.h +19 -18
  8. data/ext/libxml/ruby_xml_document.c +1111 -1115
  9. data/ext/libxml/ruby_xml_document.h +27 -24
  10. data/ext/libxml/ruby_xml_dtd.c +168 -168
  11. data/ext/libxml/ruby_xml_html_parser.c +449 -450
  12. data/ext/libxml/ruby_xml_html_parser.h +1 -1
  13. data/ext/libxml/ruby_xml_input_cbg.c +158 -158
  14. data/ext/libxml/ruby_xml_node.c +2410 -2395
  15. data/ext/libxml/ruby_xml_node.h +1 -1
  16. data/ext/libxml/ruby_xml_node_set.c +170 -170
  17. data/ext/libxml/ruby_xml_node_set.h +1 -1
  18. data/ext/libxml/ruby_xml_ns.c +153 -153
  19. data/ext/libxml/ruby_xml_ns.h +1 -1
  20. data/ext/libxml/ruby_xml_parser.c +1425 -1422
  21. data/ext/libxml/ruby_xml_parser.h +1 -1
  22. data/ext/libxml/ruby_xml_parser_context.c +750 -716
  23. data/ext/libxml/ruby_xml_parser_context.h +1 -1
  24. data/ext/libxml/ruby_xml_reader.c +900 -896
  25. data/ext/libxml/ruby_xml_sax_parser.c +485 -485
  26. data/ext/libxml/ruby_xml_sax_parser.h +1 -1
  27. data/ext/libxml/ruby_xml_schema.c +146 -142
  28. data/ext/libxml/ruby_xml_state.c +5 -6
  29. data/ext/libxml/ruby_xml_state.h +1 -0
  30. data/ext/libxml/ruby_xml_tree.c +43 -43
  31. data/ext/libxml/ruby_xml_tree.h +1 -1
  32. data/ext/libxml/ruby_xml_xinclude.c +20 -20
  33. data/ext/libxml/ruby_xml_xinclude.h +1 -1
  34. data/ext/libxml/ruby_xml_xpath.c +243 -252
  35. data/ext/libxml/ruby_xml_xpath.h +1 -1
  36. data/ext/libxml/ruby_xml_xpath_context.c +118 -118
  37. data/ext/libxml/ruby_xml_xpath_context.h +1 -1
  38. data/ext/libxml/ruby_xml_xpath_object.c +43 -29
  39. data/ext/libxml/ruby_xml_xpath_object.h +0 -1
  40. data/ext/libxml/ruby_xml_xpointer.c +100 -100
  41. data/ext/libxml/ruby_xml_xpointer.h +1 -1
  42. data/ext/libxml/ruby_xml_xpointer_context.c +21 -21
  43. data/ext/libxml/ruby_xml_xpointer_context.h +1 -1
  44. data/ext/libxml/sax_parser_callbacks.inc +213 -213
  45. data/ext/libxml/version.h +9 -9
  46. data/lib/libxml.rb +24 -3
  47. data/mingw/libiconv-2.dll +0 -0
  48. data/mingw/libxml2-2.dll +0 -0
  49. data/mingw/libxml_ruby.so +0 -0
  50. data/mingw/mingw.rake +36 -0
  51. data/test/dtd-test.rb +24 -24
  52. data/test/etc_doc_to_s.rb +1 -3
  53. data/test/ets_copy_bug.rb +21 -21
  54. data/test/ets_copy_bug2.rb +32 -32
  55. data/test/ets_copy_bug3.rb +38 -0
  56. data/test/ets_doc_file.rb +1 -0
  57. data/test/{model/default_validation_bug.rb → gc.log} +0 -0
  58. data/test/merge_bug.rb +55 -55
  59. data/test/schema-test.rb +74 -74
  60. data/test/tc_well_formed.rb +11 -0
  61. data/test/tc_xml_document.rb +52 -52
  62. data/test/tc_xml_document_write.rb +24 -24
  63. data/test/tc_xml_document_write2.rb +54 -54
  64. data/test/tc_xml_document_write3.rb +96 -96
  65. data/test/tc_xml_html_parser.rb +63 -63
  66. data/test/tc_xml_node.rb +59 -59
  67. data/test/tc_xml_node2.rb +25 -25
  68. data/test/tc_xml_node3.rb +27 -27
  69. data/test/tc_xml_node4.rb +86 -86
  70. data/test/tc_xml_node5.rb +52 -52
  71. data/test/tc_xml_node6.rb +27 -27
  72. data/test/tc_xml_node7.rb +35 -35
  73. data/test/tc_xml_node8.rb +32 -32
  74. data/test/tc_xml_node9.rb +32 -32
  75. data/test/tc_xml_node_set.rb +24 -24
  76. data/test/tc_xml_node_set2.rb +37 -37
  77. data/test/tc_xml_node_xlink.rb +28 -28
  78. data/test/tc_xml_parser.rb +190 -178
  79. data/test/tc_xml_parser2.rb +16 -17
  80. data/test/tc_xml_parser3.rb +23 -23
  81. data/test/tc_xml_parser4.rb +33 -33
  82. data/test/tc_xml_parser5.rb +27 -27
  83. data/test/tc_xml_parser6.rb +23 -23
  84. data/test/tc_xml_parser7.rb +28 -28
  85. data/test/tc_xml_parser8.rb +32 -32
  86. data/test/tc_xml_parser9.rb +11 -0
  87. data/test/tc_xml_parser_context.rb +88 -88
  88. data/test/tc_xml_reader.rb +112 -109
  89. data/test/tc_xml_sax_parser.rb +104 -94
  90. data/test/tc_xml_sax_parser2.rb +51 -0
  91. data/test/tc_xml_xinclude.rb +30 -30
  92. data/test/tc_xml_xpath.rb +38 -38
  93. data/test/tc_xml_xpath2.rb +14 -0
  94. data/test/tc_xml_xpointer.rb +78 -78
  95. data/vc/libxml.sln +20 -0
  96. data/vc/libxml.vcproj +389 -0
  97. data/work/Rakefile +247 -0
  98. data/work/task/make +26 -0
  99. data/work/task/memory +37 -0
  100. data/work/task/rdoc +39 -0
  101. data/work/task/setup +1616 -0
  102. data/work/task/test +29 -0
  103. data/work/test/ets_runner.rb +33 -0
  104. data/work/test/libxml_test.rb +3 -0
  105. data/work/test/runner.rb +0 -0
  106. data/work/test/runner_ets.rb +33 -0
  107. data/work/vc/debug/libxml.exp +0 -0
  108. data/work/vc/debug/libxml.ilk +0 -0
  109. data/work/vc/debug/libxml.lib +0 -0
  110. data/work/vc/debug/libxml.pdb +0 -0
  111. data/work/vc/debug/libxml.so +0 -0
  112. metadata +158 -189
  113. data/MANIFEST +0 -138
  114. data/NOTES +0 -9
  115. data/Rakefile +0 -38
  116. data/TODO +0 -75
  117. data/VERSION +0 -1
  118. data/log/Changelog-0.txt +0 -426
  119. data/log/Changelog.txt +0 -435
  120. data/meta/project.yaml +0 -27
  121. data/meta/unixname +0 -1
  122. data/setup.rb +0 -1472
  123. data/site/css/normal.css +0 -182
  124. data/site/img/raze-tiny.png +0 -0
  125. data/site/img/red-cube.jpg +0 -0
  126. data/site/img/xml-ruby.png +0 -0
  127. data/site/index.xml +0 -43
  128. data/site/install.xml +0 -77
  129. data/site/layout.rhtml +0 -38
  130. data/site/layout.xsl +0 -67
  131. data/site/license.xml +0 -32
  132. data/site/log/changelog.xml +0 -1324
  133. data/site/log/changelog.xsl +0 -42
  134. data/test/model/merge_bug_data.xml +0 -58
  135. data/test/model/rubynet.xml +0 -78
  136. data/test/model/rubynet_project +0 -13
  137. data/test/model/saxtest.xml +0 -5
  138. data/test/model/simple.xml +0 -7
  139. data/test/model/xinclude.xml +0 -5
@@ -1,2395 +1,2410 @@
1
- /* $Id: ruby_xml_node.c 235 2007-12-11 20:28:30Z danj $ */
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
- static VALUE
14
- check_string_or_symbol( VALUE val ) {
15
- if( TYPE(val) != T_STRING && TYPE(val) != T_SYMBOL ) {
16
- rb_raise(rb_eTypeError, "wrong argument type %s (expected String or Symbol)",
17
- rb_obj_classname(val) );
18
- }
19
- return rb_obj_as_string( val );
20
- }
21
-
22
- /*
23
- * call-seq:
24
- * node.attribute? => (true|false)
25
- *
26
- * Determine whether this is an attribute node,
27
- */
28
- VALUE
29
- ruby_xml_node_attribute_q(VALUE self) {
30
- ruby_xml_node *rxn;
31
- Data_Get_Struct(self, ruby_xml_node, rxn);
32
- if (rxn->node->type == XML_ATTRIBUTE_NODE)
33
- return(Qtrue);
34
- else
35
- return(Qfalse);
36
- }
37
-
38
-
39
- /*
40
- * call-seq:
41
- * node.attribute_decl? => (true|false)
42
- *
43
- * Determine whether this is an attribute declaration node,
44
- */
45
- VALUE
46
- ruby_xml_node_attribute_decl_q(VALUE self) {
47
- ruby_xml_node *rxn;
48
- Data_Get_Struct(self, ruby_xml_node, rxn);
49
- if (rxn->node->type == XML_ATTRIBUTE_DECL)
50
- return(Qtrue);
51
- else
52
- return(Qfalse);
53
- }
54
-
55
-
56
- /*
57
- * call-seq:
58
- * node.base => "uri"
59
- *
60
- * Obtain this node's base URI.
61
- */
62
- VALUE
63
- ruby_xml_node_base_get(VALUE self) {
64
- ruby_xml_node *rxn;
65
- Data_Get_Struct(self, ruby_xml_node, rxn);
66
- if (rxn->node->doc == NULL)
67
- return(Qnil);
68
-
69
- // TODO some NULL checking, raises ArgumentError in Ruby:
70
- // ArgumentError: NULL pointer given
71
-
72
- return(rb_str_new2((const char*)xmlNodeGetBase(rxn->node->doc, rxn->node)));
73
- }
74
-
75
-
76
- // TODO node_base_set should support setting back to nil
77
-
78
- /*
79
- * call-seq:
80
- * node.base = "uri"
81
- *
82
- * Set this node's base URI.
83
- */
84
- VALUE
85
- ruby_xml_node_base_set(VALUE self, VALUE uri) {
86
- ruby_xml_node *node;
87
-
88
- Check_Type(uri, T_STRING);
89
- Data_Get_Struct(self, ruby_xml_node, node);
90
- if (node->node->doc == NULL)
91
- return(Qnil);
92
-
93
- xmlNodeSetBase(node->node, (xmlChar*)StringValuePtr(uri));
94
- return(Qtrue);
95
- }
96
-
97
-
98
- /*
99
- * call-seq:
100
- * node.cdata? => (true|false)
101
- *
102
- * Determine whether this is a #CDATA node
103
- */
104
- VALUE
105
- ruby_xml_node_cdata_q(VALUE self) {
106
- ruby_xml_node *rxn;
107
- Data_Get_Struct(self, ruby_xml_node, rxn);
108
- if (rxn->node->type == XML_CDATA_SECTION_NODE)
109
- return(Qtrue);
110
- else
111
- return(Qfalse);
112
- }
113
-
114
-
115
- /*
116
- * call-seq:
117
- * node.comment? => (true|false)
118
- *
119
- * Determine whether this is a comment node
120
- */
121
- VALUE
122
- ruby_xml_node_comment_q(VALUE self) {
123
- ruby_xml_node *rxn;
124
- Data_Get_Struct(self, ruby_xml_node, rxn);
125
- if (rxn->node->type == XML_COMMENT_NODE)
126
- return(Qtrue);
127
- else
128
- return(Qfalse);
129
- }
130
-
131
-
132
- /*
133
- * call-seq:
134
- * node << ("string" | node) => node
135
- *
136
- * Add the specified string or XML::Node to this node's
137
- * content.
138
- */
139
- VALUE
140
- ruby_xml_node_content_add(VALUE self, VALUE obj) {
141
- ruby_xml_node *node;
142
- VALUE str;
143
-
144
- Data_Get_Struct(self, ruby_xml_node, node);
145
- /* XXX This should only be legal for a CDATA type node, I think,
146
- * resulting in a merge of content, as if a string were passed
147
- * danj 070827
148
- */
149
- if (rb_obj_is_kind_of(obj, cXMLNode)) {
150
- ruby_xml_node_child_set(self, obj);
151
- return(self);
152
- } else if (TYPE(obj) == T_STRING) {
153
- xmlNodeAddContent(node->node, (xmlChar*)StringValuePtr(obj));
154
- return(self);
155
- } else {
156
- str = rb_obj_as_string(obj);
157
- if (NIL_P(str) || TYPE(str) != T_STRING)
158
- rb_raise(rb_eTypeError, "invalid argument: must be string or XML::Node");
159
-
160
- xmlNodeAddContent(node->node, (xmlChar*)StringValuePtr(str));
161
- return(self);
162
- }
163
- }
164
-
165
-
166
- /*
167
- * call-seq:
168
- * node.content => "string"
169
- *
170
- * Obtain this node's content as a string.
171
- */
172
- VALUE
173
- ruby_xml_node_content_get(VALUE self) {
174
- ruby_xml_node *rxn;
175
- xmlChar *content;
176
- VALUE out;
177
-
178
- Data_Get_Struct(self, ruby_xml_node, rxn);
179
- content = xmlNodeGetContent(rxn->node);
180
- out = rb_str_new2((const char *) content);
181
- xmlFree(content);
182
-
183
- return out;
184
- }
185
-
186
- /*
187
- * call-seq:
188
- * node.content = "string"
189
- *
190
- * Set this node's content to the specified string.
191
- */
192
- VALUE
193
- ruby_xml_node_content_set(VALUE self, VALUE content) {
194
- ruby_xml_node *node;
195
-
196
- Check_Type(content, T_STRING);
197
- Data_Get_Struct(self, ruby_xml_node, node);
198
- // XXX docs indicate need for escaping entites, need to be done? danj
199
- xmlNodeSetContent(node->node, (xmlChar*)StringValuePtr(content));
200
- return(Qtrue);
201
- }
202
-
203
-
204
- /*
205
- * call-seq:
206
- * node.content_stripped => "string"
207
- *
208
- * Obtain this node's stripped content.
209
- *
210
- * *Deprecated*: Stripped content can be obtained via the
211
- * +content+ method.
212
- */
213
- VALUE
214
- ruby_xml_node_content_stripped_get(VALUE self) {
215
- ruby_xml_node *rxn;
216
-
217
- Data_Get_Struct(self, ruby_xml_node, rxn);
218
- if (rxn->node->content == NULL)
219
- return(Qnil);
220
- else
221
- return(rb_str_new2((const char*)xmlNodeGetContent(rxn->node)));
222
- }
223
-
224
- /*
225
- * call-seq:
226
- * node.child => node
227
- *
228
- * Obtain this node's first child node, if any.
229
- */
230
- VALUE
231
- ruby_xml_node_child_get(VALUE self) {
232
- ruby_xml_node *node;
233
- xmlNodePtr tmp;
234
-
235
- Data_Get_Struct(self, ruby_xml_node, node);
236
-
237
- switch (node->node->type) {
238
- case XML_ELEMENT_NODE:
239
- case XML_ENTITY_REF_NODE:
240
- case XML_ENTITY_NODE:
241
- case XML_PI_NODE:
242
- case XML_COMMENT_NODE:
243
- case XML_DOCUMENT_NODE:
244
- #ifdef LIBXML_DOCB_ENABLED
245
- case XML_DOCB_DOCUMENT_NODE:
246
- #endif
247
- case XML_HTML_DOCUMENT_NODE:
248
- case XML_DTD_NODE:
249
- tmp = node->node->children;
250
- break;
251
- case XML_ATTRIBUTE_NODE:
252
- {
253
- xmlAttrPtr attr = (xmlAttrPtr) node->node;
254
- tmp = attr->children;
255
- break;
256
- }
257
- default:
258
- tmp = NULL;
259
- break;
260
- }
261
-
262
- if (tmp == NULL)
263
- return(Qnil);
264
- else
265
- return(ruby_xml_node2_wrap(cXMLNode, tmp));
266
- }
267
-
268
-
269
- /*
270
- * call-seq:
271
- * node.child? => (true|false)
272
- *
273
- * Determine whether this node has at least one child.
274
- */
275
- VALUE
276
- ruby_xml_node_child_q(VALUE self) {
277
- ruby_xml_node *rxn;
278
- xmlNodePtr node;
279
- Data_Get_Struct(self, ruby_xml_node, rxn);
280
-
281
- node = NULL;
282
- switch (rxn->node->type) {
283
- case XML_ELEMENT_NODE:
284
- case XML_ENTITY_REF_NODE:
285
- case XML_ENTITY_NODE:
286
- case XML_PI_NODE:
287
- case XML_COMMENT_NODE:
288
- case XML_DOCUMENT_NODE:
289
- #ifdef LIBXML_DOCB_ENABLED
290
- case XML_DOCB_DOCUMENT_NODE:
291
- #endif
292
- case XML_HTML_DOCUMENT_NODE:
293
- case XML_DTD_NODE:
294
- node = rxn->node->children;
295
- break;
296
- case XML_ATTRIBUTE_NODE:
297
- {
298
- xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
299
- node = attr->children;
300
- break;
301
- }
302
- default:
303
- node = NULL;
304
- }
305
-
306
- if (node == NULL)
307
- return(Qfalse);
308
- else
309
- return(Qtrue);
310
- }
311
-
312
- /*
313
- * underlying for child_set and child_add, difference being
314
- * former raises on implicit copy, latter does not.
315
- */
316
- VALUE
317
- ruby_xml_node_child_set_aux(VALUE self, VALUE rnode, int do_raise) {
318
- ruby_xml_node *cnode, *pnode;
319
- xmlNodePtr chld, ret;
320
- int copied=0;
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
- chld = cnode->node;
329
- /* Since an add operation may destroy a textnode by merging, we need to work
330
- * with a copy, so that the ruby instance is not left with a dangling reference
331
- */
332
- if ( chld->type == XML_TEXT_NODE ) {
333
- chld = xmlCopyNode(chld,1);
334
- copied=1;
335
- }
336
-
337
- if ( chld->parent != NULL || chld->doc != NULL ) {
338
- /* raise before copying if applicable */
339
- if ( do_raise == 1 )
340
- rb_raise(rb_eRuntimeError, "implicit copy not legal for child= or <<");
341
- chld=xmlCopyNode(chld,1);
342
- copied=1;
343
- }
344
-
345
- ret = xmlAddChild(pnode->node, chld);
346
- if (ret == NULL) {
347
- if ( copied == 1 )
348
- xmlFreeNode(chld);
349
- rb_raise(eXMLNodeFailedModify, "unable to add a child to the document");
350
- } else if ( ret==chld ) {
351
- /* child was added whole to parent and we need to return it as a new object */
352
- return ruby_xml_node2_wrap(cXMLNode,chld);
353
- }
354
- /* else */
355
- /* If it was a text node, then ret should be parent->last, so we will just return ret. */
356
- return ruby_xml_node2_wrap(cXMLNode,ret);
357
- }
358
-
359
- /*
360
- * call-seq:
361
- * node.child = node
362
- *
363
- * Set a child node for this node. Also called for <<
364
- */
365
- VALUE
366
- ruby_xml_node_child_set(VALUE self, VALUE rnode) {
367
- return ruby_xml_node_child_set_aux(self,rnode,1);
368
- }
369
-
370
- /*
371
- * call-seq:
372
- * node.child_add(node)
373
- *
374
- * Set a child node for this node.
375
- */
376
- VALUE
377
- ruby_xml_node_child_add(VALUE self, VALUE rnode) {
378
- return ruby_xml_node_child_set_aux(self,rnode,0);
379
- }
380
-
381
- /*
382
- * call-seq:
383
- * node.doc => document
384
- *
385
- * Obtain the XML::Document this node belongs to.
386
- */
387
- VALUE
388
- ruby_xml_node_doc(VALUE self) {
389
- ruby_xml_document_t *rxd;
390
- ruby_xml_node *rxn;
391
- xmlDocPtr doc=NULL;
392
- VALUE docobj;
393
-
394
- Data_Get_Struct(self, ruby_xml_node, rxn);
395
-
396
- switch (rxn->node->type) {
397
- case XML_DOCUMENT_NODE:
398
- #ifdef LIBXML_DOCB_ENABLED
399
- case XML_DOCB_DOCUMENT_NODE:
400
- #endif
401
- case XML_HTML_DOCUMENT_NODE:
402
- doc = NULL;
403
- break;
404
- case XML_ATTRIBUTE_NODE:
405
- {
406
- xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
407
- doc = attr->doc;
408
- break;
409
- }
410
- case XML_NAMESPACE_DECL:
411
- doc = NULL;
412
- break;
413
- default:
414
- doc = rxn->node->doc;
415
- break;
416
- }
417
-
418
- if (doc == NULL)
419
- return(Qnil);
420
-
421
- if ( doc->_private == NULL )
422
- rb_raise(rb_eRuntimeError,"existing document object has no ruby-instance");
423
-
424
- return (VALUE)doc->_private;
425
- }
426
-
427
-
428
- /*
429
- * call-seq:
430
- * node.docbook? => (true|false)
431
- *
432
- * Determine whether this is a docbook node.
433
- */
434
- VALUE
435
- ruby_xml_node_docbook_doc_q(VALUE self) {
436
- #ifdef LIBXML_DOCB_ENABLED
437
- ruby_xml_node *rxn;
438
- Data_Get_Struct(self, ruby_xml_node, rxn);
439
- if (rxn->node->type == XML_DOCB_DOCUMENT_NODE)
440
- return(Qtrue);
441
- else
442
- return(Qfalse);
443
- #else
444
- rb_warn("libxml compiled without docbook support");
445
- return(Qfalse);
446
- #endif
447
- }
448
-
449
-
450
- /*
451
- * call-seq:
452
- * node.doctype? => (true|false)
453
- *
454
- * Determine whether this is a DOCTYPE node.
455
- */
456
- VALUE
457
- ruby_xml_node_doctype_q(VALUE self) {
458
- ruby_xml_node *rxn;
459
- Data_Get_Struct(self, ruby_xml_node, rxn);
460
- if (rxn->node->type == XML_DOCUMENT_TYPE_NODE)
461
- return(Qtrue);
462
- else
463
- return(Qfalse);
464
- }
465
-
466
-
467
- /*
468
- * call-seq:
469
- * node.document? => (true|false)
470
- *
471
- * Determine whether this is a document node.
472
- */
473
- VALUE
474
- ruby_xml_node_document_q(VALUE self) {
475
- ruby_xml_node *rxn;
476
- Data_Get_Struct(self, ruby_xml_node, rxn);
477
- if (rxn->node->type == XML_DOCUMENT_NODE)
478
- return(Qtrue);
479
- else
480
- return(Qfalse);
481
- }
482
-
483
-
484
- /*
485
- * call-seq:
486
- * node.dtd? => (true|false)
487
- *
488
- * Determine whether this is a DTD node.
489
- */
490
- VALUE
491
- ruby_xml_node_dtd_q(VALUE self) {
492
- ruby_xml_node *rxn;
493
- Data_Get_Struct(self, ruby_xml_node, rxn);
494
- if (rxn->node->type == XML_DTD_NODE)
495
- return(Qtrue);
496
- else
497
- return(Qfalse);
498
- }
499
-
500
-
501
- /*
502
- * call-seq:
503
- * node.dump => (true|nil)
504
- *
505
- * Dump this node to stdout.
506
- */
507
- VALUE
508
- ruby_xml_node_dump(VALUE self) {
509
- ruby_xml_node *rxn;
510
- xmlBufferPtr buf;
511
-
512
- Data_Get_Struct(self, ruby_xml_node, rxn);
513
-
514
- if (rxn->node->doc == NULL)
515
- return(Qnil);
516
-
517
- buf = xmlBufferCreate();
518
- xmlNodeDump(buf, rxn->node->doc, rxn->node, 0, 1);
519
- xmlBufferDump(stdout, buf);
520
- xmlBufferFree(buf);
521
- return(Qtrue);
522
- }
523
-
524
-
525
- /*
526
- * call-seq:
527
- * node.debug_dump => (true|nil)
528
- *
529
- * Dump this node to stdout, including any debugging
530
- * information.
531
- */
532
- VALUE
533
- ruby_xml_node_debug_dump(VALUE self) {
534
- ruby_xml_node *rxn;
535
- Data_Get_Struct(self, ruby_xml_node, rxn);
536
-
537
- if (rxn->node->doc == NULL)
538
- return(Qnil);
539
-
540
- xmlElemDump(stdout, rxn->node->doc, rxn->node);
541
- return(Qtrue);
542
- }
543
-
544
-
545
- /*
546
- * call-seq:
547
- * node.element? => (true|false)
548
- *
549
- * Determine whether this is an element node.
550
- */
551
- VALUE
552
- ruby_xml_node_element_q(VALUE self) {
553
- ruby_xml_node *rxn;
554
- Data_Get_Struct(self, ruby_xml_node, rxn);
555
- if (rxn->node->type == XML_ELEMENT_NODE)
556
- return(Qtrue);
557
- else
558
- return(Qfalse);
559
- }
560
-
561
-
562
- /*
563
- * call-seq:
564
- * node.element_decl? => (true|false)
565
- *
566
- * Determine whether this is an element declaration node.
567
- */
568
- VALUE
569
- ruby_xml_node_element_decl_q(VALUE self) {
570
- ruby_xml_node *rxn;
571
- Data_Get_Struct(self, ruby_xml_node, rxn);
572
- if (rxn->node->type == XML_ELEMENT_DECL)
573
- return(Qtrue);
574
- else
575
- return(Qfalse);
576
- }
577
-
578
-
579
- /*
580
- * call-seq:
581
- * node.empty? => (true|false)
582
- *
583
- * Determine whether this node is empty.
584
- */
585
- VALUE
586
- ruby_xml_node_empty_q(VALUE self) {
587
- ruby_xml_node *rxn;
588
- Data_Get_Struct(self, ruby_xml_node, rxn);
589
- if (rxn->node == NULL)
590
- return(Qnil);
591
-
592
- return((xmlIsBlankNode(rxn->node) == 1) ? Qtrue : Qfalse);
593
- }
594
-
595
-
596
- /*
597
- * call-seq:
598
- * node.entity? => (true|false)
599
- *
600
- * Determine whether this is an entity node.
601
- */
602
- VALUE
603
- ruby_xml_node_entity_q(VALUE self) {
604
- ruby_xml_node *rxn;
605
- Data_Get_Struct(self, ruby_xml_node, rxn);
606
- if (rxn->node->type == XML_ENTITY_NODE)
607
- return(Qtrue);
608
- else
609
- return(Qfalse);
610
- }
611
-
612
-
613
- /*
614
- * call-seq:
615
- * node.entity_ref? => (true|false)
616
- *
617
- * Determine whether this is an entity reference node.
618
- */
619
- VALUE
620
- ruby_xml_node_entity_ref_q(VALUE self) {
621
- ruby_xml_node *rxn;
622
- Data_Get_Struct(self, ruby_xml_node, rxn);
623
- if (rxn->node->type == XML_ENTITY_REF_NODE)
624
- return(Qtrue);
625
- else
626
- return(Qfalse);
627
- }
628
-
629
- VALUE ruby_xml_node_to_s(VALUE self);
630
-
631
- /*
632
- * call-seq:
633
- * node.eql?(other_node) => (true|false)
634
- *
635
- * Test equality between the two nodes. Equality is determined based
636
- * on the XML representation of the nodes.
637
- */
638
- VALUE
639
- ruby_xml_node_eql_q(VALUE self, VALUE other) {
640
- // TODO this isn't the best way to handle this
641
- ruby_xml_node *rxn, *orxn;
642
- VALUE thisxml, otherxml;
643
- Data_Get_Struct(self, ruby_xml_node, rxn);
644
- Data_Get_Struct(other, ruby_xml_node, orxn);
645
- thisxml = ruby_xml_node_to_s(self);
646
- otherxml = ruby_xml_node_to_s(other);
647
-
648
- return(rb_funcall(thisxml, rb_intern("=="), 1, otherxml));
649
- }
650
-
651
-
652
- /*
653
- * call-seq:
654
- * node.find(xpath_expr, namespace = [any]) => nodeset
655
- *
656
- * Find nodes matching the specified xpath expression, optionally
657
- * using the specified namespaces. Returns an XML::Node::Set.
658
- */
659
- VALUE
660
- ruby_xml_node_find(int argc, VALUE *argv, VALUE self) {
661
- if (argc > 2 || argc < 1)
662
- rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
663
-
664
- return(ruby_xml_xpath_find2(self,argv[0],(argc==2)?argv[1]:Qnil));
665
- }
666
-
667
- /*
668
- * call-seq:
669
- * node.find_first(xpath_expr, namespace = [any]) => nodeset
670
- *
671
- * Find the first node matching the specified xpath expression, optionally
672
- * using the specified namespaces. Returns an XML::Node.
673
- */
674
- VALUE
675
- ruby_xml_node_find_first(int argc, VALUE *argv, VALUE self) {
676
- return ruby_xml_xpath_object_first(ruby_xml_node_find(argc, argv, self));
677
- }
678
-
679
-
680
- /*
681
- * call-seq:
682
- * node.fragment? => (true|false)
683
- *
684
- * Determine whether this node is a fragment.
685
- */
686
- VALUE
687
- ruby_xml_node_fragment_q(VALUE self) {
688
- ruby_xml_node *rxn;
689
- Data_Get_Struct(self, ruby_xml_node, rxn);
690
- if (rxn->node->type == XML_DOCUMENT_FRAG_NODE)
691
- return(Qtrue);
692
- else
693
- return(Qfalse);
694
- }
695
-
696
- /*
697
- * call-seq:
698
- * node.hash => fixnum
699
- *
700
- * Returns the hash-code for this node. This is the hash of the XML
701
- * representation in order to be consistent with eql.
702
- */
703
- VALUE
704
- ruby_xml_node_hash(VALUE self) {
705
- ruby_xml_node *rxn;
706
- VALUE thisxml;
707
- Data_Get_Struct(self, ruby_xml_node, rxn);
708
- thisxml = ruby_xml_node_to_s(self);
709
-
710
- return(rb_funcall(thisxml, rb_intern("hash"), 0));
711
- }
712
-
713
-
714
- /*
715
- * call-seq:
716
- * node.html_doc? => (true|false)
717
- *
718
- * Determine whether this node is an html document node.
719
- */
720
- VALUE
721
- ruby_xml_node_html_doc_q(VALUE self) {
722
- ruby_xml_node *rxn;
723
- Data_Get_Struct(self, ruby_xml_node, rxn);
724
- if (rxn->node->type == XML_HTML_DOCUMENT_NODE)
725
- return(Qtrue);
726
- else
727
- return(Qfalse);
728
- }
729
-
730
- /*
731
- * call-seq:
732
- * XML::Node.new_cdata(content = nil) => node
733
- *
734
- * Create a new #CDATA node, optionally setting
735
- * the node's content.
736
- */
737
- VALUE
738
- ruby_xml_node_new_cdata(int argc, VALUE *argv, VALUE class) {
739
- xmlNodePtr xnode;
740
- VALUE node, str=Qnil;
741
-
742
- switch(argc) {
743
- case 1:
744
- str = argv[0];
745
- Check_Type(str, T_STRING);
746
- if (!NIL_P(str)) {
747
- xnode = xmlNewCDataBlock(NULL, (xmlChar*)StringValuePtr(str), xmlStrlen((xmlChar*)StringValuePtr(str)));
748
- } else {
749
- xnode = xmlNewCDataBlock(NULL, NULL , 0);
750
- }
751
-
752
- if (xnode == NULL)
753
- return(Qnil);
754
-
755
- return ruby_xml_node2_wrap(class,xnode);
756
-
757
- default:
758
- rb_raise(rb_eArgError, "wrong number of arguments (1)");
759
- }
760
-
761
- // not reached
762
- return(Qnil);
763
- }
764
-
765
-
766
- /*
767
- * call-seq:
768
- * XML::Node.new_comment(content = nil) => node
769
- *
770
- * Create a new comment node, optionally setting
771
- * the node's content.
772
- *
773
- */
774
- VALUE
775
- ruby_xml_node_new_comment(int argc, VALUE *argv, VALUE class) {
776
- xmlNodePtr xnode;
777
- VALUE node, str=Qnil;
778
-
779
- switch(argc) {
780
- case 1:
781
- str = argv[0];
782
- Check_Type(str, T_STRING);
783
- // TODO xmlNewComment wrongly? adds \n before and after the comment
784
- if (!NIL_P(str)) {
785
- xnode = xmlNewComment((xmlChar*)StringValuePtr(str));
786
- } else {
787
- xnode = xmlNewComment(NULL);
788
- }
789
-
790
- if (xnode == NULL)
791
- return(Qnil);
792
-
793
- return ruby_xml_node2_wrap(class,xnode);
794
-
795
- default:
796
- rb_raise(rb_eArgError, "wrong number of arguments (1)");
797
- }
798
-
799
- // not reached
800
- return(Qnil);
801
- }
802
-
803
-
804
- /*
805
- * call-seq:
806
- * node.lang => "string"
807
- *
808
- * Obtain the language set for this node, if any.
809
- * This is set in XML via the xml:lang attribute.
810
- */
811
- VALUE
812
- ruby_xml_node_lang_get(VALUE self) {
813
- ruby_xml_node *rxn;
814
- xmlChar *lang;
815
-
816
- Data_Get_Struct(self, ruby_xml_node, rxn);
817
- lang = xmlNodeGetLang(rxn->node);
818
-
819
- if (lang == NULL)
820
- return(Qnil);
821
- else
822
- return(rb_str_new2((const char*)lang));
823
- }
824
-
825
-
826
- // TODO node_lang_set should support setting back to nil
827
-
828
- /*
829
- * call-seq:
830
- * node.lang = "string"
831
- *
832
- * Set the language for this node. This affects the value
833
- * of the xml:lang attribute.
834
- */
835
- VALUE
836
- ruby_xml_node_lang_set(VALUE self, VALUE lang) {
837
- ruby_xml_node *node;
838
-
839
- Check_Type(lang, T_STRING);
840
- Data_Get_Struct(self, ruby_xml_node, node);
841
- xmlNodeSetLang(node->node, (xmlChar*)StringValuePtr(lang));
842
-
843
- return(Qtrue);
844
- }
845
-
846
-
847
- /*
848
- * call-seq:
849
- * node.last => node
850
- *
851
- * Obtain the last child node of this node, if any.
852
- */
853
- VALUE
854
- ruby_xml_node_last_get(VALUE self) {
855
- ruby_xml_node *rxn;
856
- xmlNodePtr node;
857
-
858
- Data_Get_Struct(self, ruby_xml_node, rxn);
859
-
860
- switch (rxn->node->type) {
861
- case XML_ELEMENT_NODE:
862
- case XML_ENTITY_REF_NODE:
863
- case XML_ENTITY_NODE:
864
- case XML_PI_NODE:
865
- case XML_COMMENT_NODE:
866
- case XML_DOCUMENT_NODE:
867
- #ifdef LIBXML_DOCB_ENABLED
868
- case XML_DOCB_DOCUMENT_NODE:
869
- #endif
870
- case XML_HTML_DOCUMENT_NODE:
871
- case XML_DTD_NODE:
872
- node = rxn->node->last;
873
- break;
874
- case XML_ATTRIBUTE_NODE:
875
- {
876
- xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
877
- node = attr->last;
878
- }
879
- default:
880
- node = NULL;
881
- break;
882
- }
883
-
884
- if (node == NULL)
885
- return(Qnil);
886
- else
887
- return(ruby_xml_node2_wrap(cXMLNode, node));
888
- }
889
-
890
-
891
- /*
892
- * call-seq:
893
- * node.last? => (true|false)
894
- *
895
- * Determine whether this node has a last child node.
896
- */
897
- VALUE
898
- ruby_xml_node_last_q(VALUE self) {
899
- ruby_xml_node *rxn;
900
- xmlNodePtr node;
901
-
902
- Data_Get_Struct(self, ruby_xml_node, rxn);
903
-
904
- switch (rxn->node->type) {
905
- case XML_ELEMENT_NODE:
906
- case XML_ENTITY_REF_NODE:
907
- case XML_ENTITY_NODE:
908
- case XML_PI_NODE:
909
- case XML_COMMENT_NODE:
910
- case XML_DOCUMENT_NODE:
911
- #ifdef LIBXML_DOCB_ENABLED
912
- case XML_DOCB_DOCUMENT_NODE:
913
- #endif
914
- case XML_HTML_DOCUMENT_NODE:
915
- case XML_DTD_NODE:
916
- node = rxn->node->last;
917
- break;
918
- case XML_ATTRIBUTE_NODE:
919
- {
920
- xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
921
- node = attr->last;
922
- }
923
- default:
924
- node = NULL;
925
- break;
926
- }
927
-
928
- if (node == NULL)
929
- return(Qfalse);
930
- else
931
- return(Qtrue);
932
- }
933
-
934
-
935
- /*
936
- * call-seq:
937
- * node.line_num => num
938
- *
939
- * Obtain the line number (in the XML document) that this
940
- * node was read from. If +default_line_numbers+ is set
941
- * false (the default), this method returns zero.
942
- */
943
- VALUE
944
- ruby_xml_node_line_num(VALUE self) {
945
- ruby_xml_node *rxn;
946
- long line_num;
947
- Data_Get_Struct(self, ruby_xml_node, rxn);
948
-
949
- if (!xmlLineNumbersDefaultValue)
950
- rb_warn("Line numbers were not retained: use XML::Parser::default_line_numbers=true");
951
-
952
- line_num = xmlGetLineNo(rxn->node);
953
- if (line_num == -1)
954
- return(Qnil);
955
- else
956
- return(INT2NUM((long)line_num));
957
- }
958
-
959
-
960
- /*
961
- * call-seq:
962
- * node.xlink? => (true|false)
963
- *
964
- * Determine whether this node is an xlink node.
965
- */
966
- VALUE
967
- ruby_xml_node_xlink_q(VALUE self) {
968
- ruby_xml_node *node;
969
- xlinkType xlt;
970
-
971
- Data_Get_Struct(self, ruby_xml_node, node);
972
- xlt = xlinkIsLink(node->node->doc, node->node);
973
-
974
- if (xlt == XLINK_TYPE_NONE)
975
- return(Qfalse);
976
- else
977
- return(Qtrue);
978
- }
979
-
980
-
981
- /*
982
- * call-seq:
983
- * node.xlink_type => num
984
- *
985
- * Obtain the type identifier for this xlink, if applicable.
986
- * If this is not an xlink node (see +xlink?+), will return
987
- * nil.
988
- */
989
- VALUE
990
- ruby_xml_node_xlink_type(VALUE self) {
991
- ruby_xml_node *node;
992
- ruby_xml_document_t *doc;
993
- xlinkType xlt;
994
-
995
- Data_Get_Struct(self, ruby_xml_node, node);
996
- xlt = xlinkIsLink(node->node->doc, node->node);
997
-
998
- if (xlt == XLINK_TYPE_NONE)
999
- return(Qnil);
1000
- else
1001
- return(INT2NUM(xlt));
1002
- }
1003
-
1004
-
1005
- /*
1006
- * call-seq:
1007
- * node.xlink_type_name => "string"
1008
- *
1009
- * Obtain the type name for this xlink, if applicable.
1010
- * If this is not an xlink node (see +xlink?+), will return
1011
- * nil.
1012
- */
1013
- VALUE
1014
- ruby_xml_node_xlink_type_name(VALUE self) {
1015
- ruby_xml_node *node;
1016
- ruby_xml_document_t *doc;
1017
- xlinkType xlt;
1018
-
1019
- Data_Get_Struct(self, ruby_xml_node, node);
1020
- xlt = xlinkIsLink(node->node->doc, node->node);
1021
-
1022
- switch(xlt) {
1023
- case XLINK_TYPE_NONE:
1024
- return(Qnil);
1025
- case XLINK_TYPE_SIMPLE:
1026
- return(rb_str_new2("simple"));
1027
- case XLINK_TYPE_EXTENDED:
1028
- return(rb_str_new2("extended"));
1029
- case XLINK_TYPE_EXTENDED_SET:
1030
- return(rb_str_new2("extended_set"));
1031
- default:
1032
- rb_fatal("Unknowng xlink type, %d", xlt);
1033
- }
1034
- }
1035
-
1036
- /*
1037
- * call-seq:
1038
- * node.name => "string"
1039
- *
1040
- * Obtain this node's name.
1041
- */
1042
- VALUE
1043
- ruby_xml_node_name_get(VALUE self) {
1044
- ruby_xml_node *rxn;
1045
- const xmlChar *name;
1046
-
1047
- Data_Get_Struct(self, ruby_xml_node, rxn);
1048
-
1049
- switch (rxn->node->type) {
1050
- case XML_DOCUMENT_NODE:
1051
- #ifdef LIBXML_DOCB_ENABLED
1052
- case XML_DOCB_DOCUMENT_NODE:
1053
- #endif
1054
- case XML_HTML_DOCUMENT_NODE:
1055
- {
1056
- xmlDocPtr doc = (xmlDocPtr) rxn->node;
1057
- name = doc->URL;
1058
- break;
1059
- }
1060
- case XML_ATTRIBUTE_NODE:
1061
- {
1062
- xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1063
- name = attr->name;
1064
- break;
1065
- }
1066
- case XML_NAMESPACE_DECL:
1067
- {
1068
- xmlNsPtr ns = (xmlNsPtr) rxn->node;
1069
- name = ns->prefix;
1070
- break;
1071
- }
1072
- default:
1073
- name = rxn->node->name;
1074
- break;
1075
- }
1076
-
1077
- if (rxn->node->name == NULL)
1078
- return(Qnil);
1079
- else
1080
- return(rb_str_new2((const char*)name));
1081
- }
1082
-
1083
-
1084
- /*
1085
- * call-seq:
1086
- * node.name = "string"
1087
- *
1088
- * Set this node's name.
1089
- */
1090
- VALUE
1091
- ruby_xml_node_name_set(VALUE self, VALUE name) {
1092
- ruby_xml_node *node;
1093
-
1094
- Check_Type(name, T_STRING);
1095
- Data_Get_Struct(self, ruby_xml_node, node);
1096
- xmlNodeSetName(node->node, (xmlChar*)StringValuePtr(name));
1097
- return(Qtrue);
1098
- }
1099
-
1100
-
1101
- /*
1102
- * call-seq:
1103
- * node.namespace => [namespace, ..., namespace]
1104
- *
1105
- * Obtain an array of +XML::NS+ objects representing
1106
- * this node's xmlns attributes
1107
- */
1108
- VALUE
1109
- ruby_xml_node_namespace_get(VALUE self) {
1110
- ruby_xml_node *node;
1111
- xmlNsPtr *nsList, *cur;
1112
- VALUE arr, ns;
1113
-
1114
- Data_Get_Struct(self, ruby_xml_node, node);
1115
- if (node->node == NULL)
1116
- return(Qnil);
1117
-
1118
- nsList = xmlGetNsList(node->node->doc, node->node);
1119
-
1120
- if (nsList == NULL)
1121
- return(Qnil);
1122
-
1123
- arr = rb_ary_new();
1124
- for (cur = nsList; *cur != NULL; cur++) {
1125
- ns = ruby_xml_ns_new2(cXMLNS, ruby_xml_document_wrap(cXMLDocument,node->node->doc), *cur);
1126
- if (ns == Qnil)
1127
- continue;
1128
- else
1129
- rb_ary_push(arr, ns);
1130
- }
1131
- xmlFree(nsList);
1132
-
1133
- return(arr);
1134
- }
1135
-
1136
-
1137
- /*
1138
- * call-seq:
1139
- * node.namespace_node => namespace.
1140
- *
1141
- * Obtain this node's namespace node.
1142
- */
1143
- VALUE
1144
- ruby_xml_node_namespace_get_node(VALUE self) {
1145
- ruby_xml_node *node;
1146
-
1147
- Data_Get_Struct(self, ruby_xml_node, node);
1148
- if (node->node->ns == NULL)
1149
- return(Qnil);
1150
- else
1151
- return ruby_xml_ns_new2(cXMLNS,
1152
- ruby_xml_document_wrap(cXMLDocument,node->node->doc),
1153
- node->node->ns);
1154
- }
1155
-
1156
- // TODO namespace_set can take varargs (in fact, must if used
1157
- // with strings), but I cannot see how you can call
1158
- // that version, apart from with 'send'
1159
- //
1160
- // Would sure be nice to support foo.namespace['foo'] = 'bar'
1161
- // but maybe that's not practical...
1162
-
1163
- /*
1164
- * call-seq:
1165
- * node.namespace = namespace
1166
- *
1167
- * Add the specified XML::NS object to this node's xmlns attributes.
1168
- */
1169
- VALUE
1170
- ruby_xml_node_namespace_set(int argc, VALUE *argv, VALUE self) {
1171
- VALUE rns, rprefix;
1172
- ruby_xml_node *rxn;
1173
- ruby_xml_ns *rxns;
1174
- xmlNsPtr ns;
1175
- char *cp, *href;
1176
-
1177
- Data_Get_Struct(self, ruby_xml_node, rxn);
1178
- switch (argc) {
1179
- case 1:
1180
- rns = argv[0];
1181
- if (TYPE(rns) == T_STRING) {
1182
- cp = strchr(StringValuePtr(rns), (int)':');
1183
- if (cp == NULL) {
1184
- rprefix = rns;
1185
- href = NULL;
1186
- } else {
1187
- rprefix = rb_str_new(StringValuePtr(rns), (int)((long)cp - (long)StringValuePtr(rns)));
1188
- href = &cp[1]; /* skip the : */
1189
- }
1190
- } else if (rb_obj_is_kind_of(rns, cXMLNS) == Qtrue) {
1191
- Data_Get_Struct(self, ruby_xml_ns, rxns);
1192
- xmlSetNs(rxn->node, rxns->ns);
1193
- return(rns);
1194
- } else
1195
- rb_raise(rb_eTypeError, "must pass a string or an XML::Ns object");
1196
-
1197
- /* Fall through to next case because when argc == 1, we need to
1198
- * manually setup the additional args unless the arg passed is of
1199
- * cXMLNS type */
1200
- case 2:
1201
- /* Don't want this code run in the fall through case */
1202
- if (argc == 2) {
1203
- rprefix = argv[0];
1204
- href = StringValuePtr(argv[1]);
1205
- }
1206
-
1207
- ns = xmlNewNs(rxn->node, (xmlChar*)href, (xmlChar*)StringValuePtr(rprefix));
1208
- if (ns == NULL)
1209
- rb_raise(eXMLNodeSetNamespace, "unable to set the namespace");
1210
- else
1211
- return ruby_xml_ns_new2(cXMLNS, ruby_xml_document_wrap(cXMLDocument,rxn->node->doc), ns);
1212
- break;
1213
-
1214
- default:
1215
- rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
1216
- }
1217
-
1218
- /* can't get here */
1219
- return(Qnil);
1220
- }
1221
-
1222
-
1223
- /*
1224
- * call-seq:
1225
- * node.namespace? => (true|false)
1226
- *
1227
- * Determine whether this node *is* (not has) a namespace
1228
- * node.
1229
- */
1230
- VALUE
1231
- ruby_xml_node_namespace_q(VALUE self) {
1232
- ruby_xml_node *rxn;
1233
- Data_Get_Struct(self, ruby_xml_node, rxn);
1234
- if (rxn->node->type == XML_NAMESPACE_DECL)
1235
- return(Qtrue);
1236
- else
1237
- return(Qfalse);
1238
- }
1239
-
1240
- /*
1241
- * memory2 implementation: xmlNode->_private holds a reference
1242
- * to the wrapping ruby object VALUE when there is one.
1243
- * traversal for marking is upward, and top levels are marked
1244
- * through and lower level mark entry.
1245
- *
1246
- * All ruby retrieval for an xml
1247
- * node will result in the same ruby instance. When all handles to them
1248
- * go out of scope, then free gets called and _private is set to NULL.
1249
- * If the xmlNode has no parent or document, then call xmlFree.
1250
- */
1251
- void
1252
- ruby_xml_node2_free(ruby_xml_node *rxn) {
1253
-
1254
- if (rxn == NULL ) return;
1255
-
1256
- if (rxn->node != NULL ) {
1257
- rxn->node->_private=NULL;
1258
-
1259
- if ( rxn->node->doc==NULL && rxn->node->parent==NULL ) {
1260
- #ifdef NODE_DEBUG
1261
- fprintf(stderr,"ruby_xml_node2_free free rxn=0x%x xn=0x%x o=0x%x\n",(long)rxn,(long)rxn->node,(long)rxn->node->_private);
1262
- #endif
1263
- xmlFreeNode(rxn->node);
1264
- }
1265
-
1266
- rxn->node=NULL;
1267
- }
1268
-
1269
- free(rxn);
1270
- }
1271
-
1272
- void
1273
- ruby_xml_node_mark_common(xmlNodePtr node) {
1274
- if (node->parent == NULL ) {
1275
- #ifdef NODE_DEBUG
1276
- fprintf(stderr,"mark no parent r=0x%x *n=0x%x\n",rxn,node);
1277
- #endif
1278
- } else if ( node->doc != NULL ) {
1279
- if (node->doc->_private == NULL) {
1280
- rb_bug("XmlNode Doc is not bound! (%s:%d)",
1281
- __FILE__,__LINE__);
1282
- }
1283
- rb_gc_mark((VALUE)node->doc->_private);
1284
- } else {
1285
- while (node->parent != NULL )
1286
- node=node->parent;
1287
- if (node->_private == NULL )
1288
- rb_warning("XmlNode Root Parent is not bound! (%s:%d)",
1289
- __FILE__,__LINE__);
1290
- else {
1291
- #ifdef NODE_DEBUG
1292
- fprintf(stderr,"mark rxn=0x%x xn=0x%x o=0x%x doc=0x%x\n",(long)rxn,(long)node,(long)node->_private,node->doc);
1293
- #endif
1294
- rb_gc_mark((VALUE)node->_private);
1295
- }
1296
- }
1297
- }
1298
-
1299
- void
1300
- ruby_xml_node2_mark(ruby_xml_node *rxn) {
1301
- xmlNodePtr node;
1302
- if (rxn->node == NULL ) return;
1303
-
1304
- if (rxn->node->_private == NULL ) {
1305
- rb_warning("XmlNode is not bound! (%s:%d)",
1306
- __FILE__,__LINE__);
1307
- return;
1308
- }
1309
-
1310
- ruby_xml_node_mark_common(rxn->node);
1311
- }
1312
-
1313
- VALUE
1314
- ruby_xml_node2_wrap(VALUE class, xmlNodePtr xnode)
1315
- {
1316
- VALUE obj;
1317
- ruby_xml_node *rxn;
1318
-
1319
- // This node is already wrapped
1320
- if (xnode->_private != NULL) {
1321
- #ifdef NODE_DEBUG
1322
- Data_Get_Struct((VALUE)xnode->_private,ruby_xml_node,rxn);
1323
- fprintf(stderr,"re-wrap rn=0x%x n*=0x%x\n",(long)rxn,(long)xnode);
1324
- #endif
1325
- return (VALUE)xnode->_private;
1326
- }
1327
-
1328
- obj=Data_Make_Struct(class,ruby_xml_node,ruby_xml_node2_mark,
1329
- ruby_xml_node2_free,rxn);
1330
-
1331
- rxn->node=xnode;
1332
- xnode->_private=(void*)obj;
1333
- #ifdef NODE_DEBUG
1334
- fprintf(stderr,"wrap rn=0x%x n*=0x%x d*=0x%x\n",
1335
- (long)rxn,(long)xnode,xnode->doc);
1336
- #endif
1337
- return obj;
1338
- }
1339
-
1340
- VALUE
1341
- ruby_xml_node2_new_native(VALUE class, VALUE ns, VALUE name)
1342
- {
1343
- VALUE obj;
1344
- xmlNodePtr xnode;
1345
- xmlNsPtr xns=NULL;
1346
- ruby_xml_node *rxn;
1347
-
1348
- if ( ! NIL_P(ns) ) {
1349
- Data_Get_Struct(ns,xmlNs,xns);
1350
- }
1351
- xnode=xmlNewNode(xns,(xmlChar*)StringValuePtr(name));
1352
- xnode->_private=NULL;
1353
-
1354
- obj=
1355
- ruby_xml_node2_wrap(class,xnode);
1356
-
1357
- rb_obj_call_init(obj,0,NULL);
1358
- return obj;
1359
- }
1360
-
1361
- VALUE
1362
- ruby_xml_node2_new_string(VALUE class, VALUE ns, VALUE name, VALUE val)
1363
- {
1364
- VALUE obj;
1365
- char* value;
1366
- obj=ruby_xml_node2_new_native(class,ns,name);
1367
- if ( ! NIL_P(val) ) {
1368
- if ( TYPE(val) != T_STRING )
1369
- val=rb_obj_as_string(val);
1370
- ruby_xml_node_content_set(obj,val);
1371
- }
1372
- return obj;
1373
- }
1374
- /*
1375
- * call-seq:
1376
- * XML::Node.new(name, content = nil) => node
1377
- * XML::Node.new_element(name, content = nil) => node
1378
- *
1379
- * Create a new element node with the specified name, optionally setting
1380
- * the node's content.
1381
- * backward compatibility for <.5 new
1382
- */
1383
- VALUE
1384
- ruby_xml_node2_new_string_bc(int argc, VALUE *argv, VALUE class)
1385
- {
1386
- VALUE content=Qnil,name=Qnil,rxnode;
1387
- switch(argc) {
1388
- case 2:
1389
- content=argv[1];
1390
- if ( TYPE(content) != T_STRING)
1391
- content=rb_obj_as_string(content);
1392
-
1393
- case 1:
1394
- name=check_string_or_symbol( argv[0] );
1395
- return ruby_xml_node2_new_string(class,Qnil,name,content);
1396
-
1397
- default:
1398
- rb_raise(rb_eArgError, "wrong number of arguments (1 or 2) given %d",argc);
1399
- }
1400
- }
1401
-
1402
- /*
1403
- * call-seq:
1404
- * node.next => node
1405
- *
1406
- * Obtain the next sibling node, if any.
1407
- */
1408
- VALUE
1409
- ruby_xml_node_next_get(VALUE self) {
1410
- ruby_xml_node *rxn;
1411
- xmlNodePtr node;
1412
- Data_Get_Struct(self, ruby_xml_node, rxn);
1413
-
1414
- switch (rxn->node->type) {
1415
- case XML_DOCUMENT_NODE:
1416
- #ifdef LIBXML_DOCB_ENABLED
1417
- case XML_DOCB_DOCUMENT_NODE:
1418
- #endif
1419
- case XML_HTML_DOCUMENT_NODE:
1420
- node = NULL;
1421
- break;
1422
- case XML_ATTRIBUTE_NODE:
1423
- {
1424
- xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1425
- node = (xmlNodePtr) attr->next;
1426
- break;
1427
- }
1428
- case XML_NAMESPACE_DECL:
1429
- {
1430
- xmlNsPtr ns = (xmlNsPtr) rxn->node;
1431
- node = (xmlNodePtr) ns->next;
1432
- break;
1433
- }
1434
- default:
1435
- node = rxn->node->next;
1436
- break;
1437
- }
1438
-
1439
- if (node == NULL) {
1440
- return(Qnil);
1441
- } else {
1442
- return(ruby_xml_node2_wrap(cXMLNode, node));
1443
- }
1444
- }
1445
-
1446
-
1447
- /*
1448
- * call-seq:
1449
- * node.next? => (true|false)
1450
- *
1451
- * Determine whether this node has a next sibling.
1452
- */
1453
- VALUE
1454
- ruby_xml_node_next_q(VALUE self) {
1455
- ruby_xml_node *rxn;
1456
- xmlNodePtr node;
1457
- Data_Get_Struct(self, ruby_xml_node, rxn);
1458
-
1459
- switch (rxn->node->type) {
1460
- case XML_DOCUMENT_NODE:
1461
- #ifdef LIBXML_DOCB_ENABLED
1462
- case XML_DOCB_DOCUMENT_NODE:
1463
- #endif
1464
- case XML_HTML_DOCUMENT_NODE:
1465
- node = NULL;
1466
- break;
1467
- case XML_ATTRIBUTE_NODE:
1468
- {
1469
- xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1470
- node = (xmlNodePtr) attr->next;
1471
- break;
1472
- }
1473
- case XML_NAMESPACE_DECL:
1474
- {
1475
- xmlNsPtr ns = (xmlNsPtr) rxn->node;
1476
- node = (xmlNodePtr) ns->next;
1477
- break;
1478
- }
1479
- default:
1480
- node = rxn->node->next;
1481
- break;
1482
- }
1483
-
1484
- if (node == NULL)
1485
- return(Qfalse);
1486
- else
1487
- return(Qtrue);
1488
- }
1489
-
1490
-
1491
- /*
1492
- * call-seq:
1493
- * node.next = node
1494
- *
1495
- * Insert the specified node as this node's next sibling.
1496
- */
1497
- VALUE
1498
- ruby_xml_node_next_set(VALUE self, VALUE rnode) {
1499
- ruby_xml_node *cnode, *pnode;
1500
- xmlNodePtr ret;
1501
-
1502
- if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
1503
- rb_raise(rb_eTypeError, "Must pass an XML::Node object");
1504
-
1505
- Data_Get_Struct(self, ruby_xml_node, pnode);
1506
- Data_Get_Struct(rnode, ruby_xml_node, cnode);
1507
-
1508
- ret = xmlAddNextSibling(pnode->node, cnode->node);
1509
- if (ret == NULL)
1510
- rb_raise(eXMLNodeFailedModify, "unable to add a sibling to the document");
1511
-
1512
- return(ruby_xml_node2_wrap(cXMLNode, ret));
1513
- }
1514
-
1515
-
1516
- /*
1517
- * call-seq:
1518
- * node.notation? => (true|false)
1519
- *
1520
- * Determine whether this is a notation node
1521
- */
1522
- VALUE
1523
- ruby_xml_node_notation_q(VALUE self) {
1524
- ruby_xml_node *rxn;
1525
- Data_Get_Struct(self, ruby_xml_node, rxn);
1526
- if (rxn->node->type == XML_NOTATION_NODE)
1527
- return(Qtrue);
1528
- else
1529
- return(Qfalse);
1530
- }
1531
-
1532
-
1533
- /*
1534
- * call-seq:
1535
- * node.ns? => (true|false)
1536
- *
1537
- * Determine whether this node is a namespace node.
1538
- */
1539
- VALUE
1540
- ruby_xml_node_ns_q(VALUE self) {
1541
- ruby_xml_node *rxn;
1542
- Data_Get_Struct(self, ruby_xml_node, rxn);
1543
- if (rxn->node->ns == NULL)
1544
- return(Qfalse);
1545
- else
1546
- return(Qtrue);
1547
- }
1548
-
1549
-
1550
- /*
1551
- * call-seq:
1552
- * node.ns_def => namespace
1553
- *
1554
- * Obtain this node's default namespace.
1555
- */
1556
- VALUE
1557
- ruby_xml_node_ns_def_get(VALUE self) {
1558
- ruby_xml_node *rxn;
1559
- Data_Get_Struct(self, ruby_xml_node, rxn);
1560
- if (rxn->node->nsDef == NULL)
1561
- return(Qnil);
1562
- else
1563
- return(ruby_xml_ns_new2(cXMLNS, ruby_xml_document_wrap(cXMLDocument,rxn->node->doc), rxn->node->nsDef));
1564
- }
1565
-
1566
-
1567
- /*
1568
- * call-seq:
1569
- * node.ns_def? => (true|false)
1570
- *
1571
- * Obtain an array of +XML::NS+ objects representing
1572
- * this node's xmlns attributes
1573
- */
1574
- VALUE
1575
- ruby_xml_node_ns_def_q(VALUE self) {
1576
- ruby_xml_node *rxn;
1577
- Data_Get_Struct(self, ruby_xml_node, rxn);
1578
- if (rxn->node->nsDef == NULL)
1579
- return(Qfalse);
1580
- else
1581
- return(Qtrue);
1582
- }
1583
-
1584
-
1585
- /*
1586
- * call-seq:
1587
- * node.parent => node
1588
- *
1589
- * Obtain this node's parent node, if any.
1590
- */
1591
- VALUE
1592
- ruby_xml_node_parent_get(VALUE self) {
1593
- ruby_xml_node *rxn;
1594
- xmlNodePtr node;
1595
-
1596
- Data_Get_Struct(self, ruby_xml_node, rxn);
1597
-
1598
- switch (rxn->node->type) {
1599
- case XML_DOCUMENT_NODE:
1600
- case XML_HTML_DOCUMENT_NODE:
1601
- #ifdef LIBXML_DOCB_ENABLED
1602
- case XML_DOCB_DOCUMENT_NODE:
1603
- #endif
1604
- node = NULL;
1605
- break;
1606
- case XML_ATTRIBUTE_NODE:
1607
- {
1608
- xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1609
- node = attr->parent;
1610
- }
1611
- case XML_ENTITY_DECL:
1612
- case XML_NAMESPACE_DECL:
1613
- case XML_XINCLUDE_START:
1614
- case XML_XINCLUDE_END:
1615
- node = NULL;
1616
- break;
1617
- default:
1618
- node = rxn->node->parent;
1619
- break;
1620
- }
1621
-
1622
- if (node == NULL)
1623
- return(Qnil);
1624
- else
1625
- return(ruby_xml_node2_wrap(cXMLNode, node));
1626
- }
1627
-
1628
-
1629
- /*
1630
- * call-seq:
1631
- * node.parent? => (true|false)
1632
- *
1633
- * Determine whether this node has a parent node.
1634
- */
1635
- VALUE
1636
- ruby_xml_node_parent_q(VALUE self) {
1637
- ruby_xml_node *rxn;
1638
- xmlNodePtr node;
1639
-
1640
- Data_Get_Struct(self, ruby_xml_node, rxn);
1641
-
1642
- switch (rxn->node->type) {
1643
- case XML_DOCUMENT_NODE:
1644
- case XML_HTML_DOCUMENT_NODE:
1645
- #ifdef LIBXML_DOCB_ENABLED
1646
- case XML_DOCB_DOCUMENT_NODE:
1647
- #endif
1648
- node = NULL;
1649
- break;
1650
- case XML_ATTRIBUTE_NODE:
1651
- {
1652
- xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1653
- node = attr->parent;
1654
- }
1655
- case XML_ENTITY_DECL:
1656
- case XML_NAMESPACE_DECL:
1657
- case XML_XINCLUDE_START:
1658
- case XML_XINCLUDE_END:
1659
- node = NULL;
1660
- break;
1661
- default:
1662
- node = rxn->node->parent;
1663
- break;
1664
- }
1665
-
1666
- if (node == NULL)
1667
- return(Qfalse);
1668
- else
1669
- return(Qtrue);
1670
- }
1671
-
1672
-
1673
- /*
1674
- * call-seq:
1675
- * node.path => path
1676
- *
1677
- * Obtain this node's path.
1678
- */
1679
- VALUE
1680
- ruby_xml_node_path(VALUE self) {
1681
- ruby_xml_node *rxn;
1682
- xmlChar *path;
1683
-
1684
- Data_Get_Struct(self, ruby_xml_node, rxn);
1685
- path = xmlGetNodePath(rxn->node);
1686
-
1687
- if (path == NULL)
1688
- return(Qnil);
1689
- else
1690
- return(rb_str_new2((const char*)path));
1691
- }
1692
-
1693
-
1694
- /*
1695
- * call-seq:
1696
- * node.pi? => (true|false)
1697
- *
1698
- * Determine whether this is a processing instruction node.
1699
- */
1700
- VALUE
1701
- ruby_xml_node_pi_q(VALUE self) {
1702
- ruby_xml_node *rxn;
1703
- Data_Get_Struct(self, ruby_xml_node, rxn);
1704
- if (rxn->node->type == XML_PI_NODE)
1705
- return(Qtrue);
1706
- else
1707
- return(Qfalse);
1708
- }
1709
-
1710
-
1711
- /*
1712
- * call-seq:
1713
- * node.pointer => node_set
1714
- *
1715
- * Evaluates an XPointer expression relative to this node.
1716
- */
1717
- VALUE
1718
- ruby_xml_node_pointer(VALUE self, VALUE xptr_str) {
1719
- return(ruby_xml_xpointer_point2(self, xptr_str));
1720
- }
1721
-
1722
-
1723
- /*
1724
- * call-seq:
1725
- * node.prev => node
1726
- *
1727
- * Obtain the previous sibling, if any.
1728
- */
1729
- VALUE
1730
- ruby_xml_node_prev_get(VALUE self) {
1731
- ruby_xml_node *rxn;
1732
- xmlNodePtr node;
1733
- Data_Get_Struct(self, ruby_xml_node, rxn);
1734
-
1735
- switch (rxn->node->type) {
1736
- case XML_DOCUMENT_NODE:
1737
- #ifdef LIBXML_DOCB_ENABLED
1738
- case XML_DOCB_DOCUMENT_NODE:
1739
- #endif
1740
- case XML_HTML_DOCUMENT_NODE:
1741
- case XML_NAMESPACE_DECL:
1742
- node = NULL;
1743
- break;
1744
- case XML_ATTRIBUTE_NODE:
1745
- {
1746
- xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1747
- node = (xmlNodePtr) attr->prev;
1748
- }
1749
- break;
1750
- default:
1751
- node = rxn->node->prev;
1752
- break;
1753
- }
1754
-
1755
- if (node == NULL)
1756
- return(Qnil);
1757
- else
1758
- return(ruby_xml_node2_wrap(cXMLNode, node));
1759
- }
1760
-
1761
-
1762
- /*
1763
- * call-seq:
1764
- * node.prev? => (true|false)
1765
- *
1766
- * Determines whether this node has a previous sibling node.
1767
- */
1768
- VALUE
1769
- ruby_xml_node_prev_q(VALUE self) {
1770
- ruby_xml_node *rxn;
1771
- xmlNodePtr node;
1772
-
1773
- Data_Get_Struct(self, ruby_xml_node, rxn);
1774
-
1775
- switch (rxn->node->type) {
1776
- case XML_DOCUMENT_NODE:
1777
- #ifdef LIBXML_DOCB_ENABLED
1778
- case XML_DOCB_DOCUMENT_NODE:
1779
- #endif
1780
- case XML_HTML_DOCUMENT_NODE:
1781
- case XML_NAMESPACE_DECL:
1782
- node = NULL;
1783
- break;
1784
- case XML_ATTRIBUTE_NODE:
1785
- {
1786
- xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1787
- node = (xmlNodePtr) attr->prev;
1788
- }
1789
- break;
1790
- default:
1791
- node = rxn->node->prev;
1792
- break;
1793
- }
1794
-
1795
- if (node == NULL)
1796
- return(Qfalse);
1797
- else
1798
- return(Qtrue);
1799
- }
1800
-
1801
-
1802
- /*
1803
- * call-seq:
1804
- * node.prev = node
1805
- *
1806
- * Insert the specified node as this node's previous sibling.
1807
- */
1808
- VALUE
1809
- ruby_xml_node_prev_set(VALUE self, VALUE rnode) {
1810
- ruby_xml_node *cnode, *pnode;
1811
- xmlNodePtr ret;
1812
-
1813
- if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
1814
- rb_raise(rb_eTypeError, "Must pass an XML::Node object");
1815
-
1816
- Data_Get_Struct(self, ruby_xml_node, pnode);
1817
- Data_Get_Struct(rnode, ruby_xml_node, cnode);
1818
-
1819
- ret = xmlAddPrevSibling(pnode->node, cnode->node);
1820
- if (ret == NULL)
1821
- rb_raise(eXMLNodeFailedModify, "unable to add a sibling to the document");
1822
-
1823
- return(ruby_xml_node2_wrap(cXMLNode, ret));
1824
- }
1825
-
1826
-
1827
- /*
1828
- * call-seq:
1829
- * node.property("name") => "string"
1830
- * node["name"] => "string"
1831
- *
1832
- * Obtain the named property.
1833
- */
1834
- VALUE
1835
- ruby_xml_node_property_get(VALUE self, VALUE prop) {
1836
- ruby_xml_node *rxn;
1837
- xmlChar *p;
1838
- VALUE r;
1839
-
1840
- prop = check_string_or_symbol( prop );
1841
-
1842
- Data_Get_Struct(self, ruby_xml_node, rxn);
1843
- p = xmlGetProp(rxn->node, (xmlChar*)StringValuePtr(prop));
1844
-
1845
- if (p == NULL)
1846
- r = Qnil;
1847
- else {
1848
- r = rb_str_new2((const char*)p);
1849
- xmlFree(p);
1850
- }
1851
-
1852
- return r;
1853
- }
1854
-
1855
-
1856
- /*
1857
- * call-seq:
1858
- * node["name"] = "string"
1859
- *
1860
- * Set the named property.
1861
- */
1862
- VALUE
1863
- ruby_xml_node_property_set(VALUE self, VALUE key, VALUE val) {
1864
- ruby_xml_node *node;
1865
- xmlAttrPtr attr;
1866
-
1867
- key = check_string_or_symbol( key );
1868
- Data_Get_Struct(self, ruby_xml_node, node);
1869
-
1870
- if( val == Qnil ) {
1871
- attr = xmlSetProp(node->node, (xmlChar*)StringValuePtr(key), NULL);
1872
- xmlRemoveProp( attr );
1873
- return Qnil;
1874
- } else {
1875
- Check_Type(val, T_STRING);
1876
- }
1877
-
1878
- attr = xmlSetProp(node->node, (xmlChar*)StringValuePtr(key), (xmlChar*)StringValuePtr(val));
1879
- if (attr == NULL) {
1880
- attr = xmlNewProp(node->node, (xmlChar*)StringValuePtr(key), (xmlChar*)StringValuePtr(val));
1881
- if (attr == NULL)
1882
- return(Qnil);
1883
- }
1884
- return(ruby_xml_attr_new(cXMLAttr, attr));
1885
- }
1886
-
1887
-
1888
- /*
1889
- * call-seq:
1890
- * node.properties => attributes
1891
- *
1892
- * Returns the +XML::Attr+ for this node.
1893
- */
1894
- VALUE
1895
- ruby_xml_node_properties_get(VALUE self) {
1896
- ruby_xml_node *node;
1897
- xmlAttrPtr attr;
1898
-
1899
- Data_Get_Struct(self, ruby_xml_node, node);
1900
-
1901
- if (node->node->type == XML_ELEMENT_NODE) {
1902
- attr = node->node->properties;
1903
-
1904
- if (attr == NULL) {
1905
- return(Qnil);
1906
- } else {
1907
- return(ruby_xml_attr_wrap(cXMLAttr, attr));
1908
- }
1909
- } else {
1910
- return(Qnil);
1911
- }
1912
- }
1913
-
1914
-
1915
- /*
1916
- * call-seq:
1917
- * node.properties? => (true|false)
1918
- *
1919
- * Determine whether this node has properties
1920
- * (attributes).
1921
- */
1922
- VALUE
1923
- ruby_xml_node_properties_q(VALUE self) {
1924
- ruby_xml_node *rxn;
1925
- Data_Get_Struct(self, ruby_xml_node, rxn);
1926
- if (rxn->node->type == XML_ELEMENT_NODE && rxn->node->properties != NULL)
1927
- return(Qtrue);
1928
- else
1929
- return(Qfalse);
1930
- }
1931
-
1932
-
1933
- /*
1934
- * call-seq:
1935
- * node.remove! => nil
1936
- *
1937
- * Removes this node from it's parent.
1938
- */
1939
- VALUE
1940
- ruby_xml_node_remove_ex(VALUE self) {
1941
- ruby_xml_node *rxn;
1942
- Data_Get_Struct(self, ruby_xml_node, rxn);
1943
- xmlUnlinkNode(rxn->node);
1944
- return(Qnil);
1945
- }
1946
-
1947
-
1948
- /*
1949
- * call-seq:
1950
- * node.search_href => namespace
1951
- *
1952
- * Search for a namespace by href.
1953
- */
1954
- VALUE
1955
- ruby_xml_node_search_href(VALUE self, VALUE href) {
1956
- ruby_xml_node *node;
1957
-
1958
- Check_Type(href, T_STRING);
1959
- Data_Get_Struct(self, ruby_xml_node, node);
1960
- return(ruby_xml_ns_new2(cXMLNS, ruby_xml_document_wrap(cXMLDocument,node->node->doc),
1961
- xmlSearchNsByHref(node->node->doc, node->node,
1962
- (xmlChar*)StringValuePtr(href))));
1963
- }
1964
-
1965
-
1966
- /*
1967
- * call-seq:
1968
- * node.search_ns => namespace
1969
- *
1970
- * Search for a namespace by namespace.
1971
- */
1972
- VALUE
1973
- ruby_xml_node_search_ns(VALUE self, VALUE ns) {
1974
- ruby_xml_node *node;
1975
-
1976
- Check_Type(ns, T_STRING);
1977
- Data_Get_Struct(self, ruby_xml_node, node);
1978
- return(ruby_xml_ns_new2(cXMLNS,
1979
- ruby_xml_document_wrap(cXMLDocument,node->node->doc),
1980
- xmlSearchNs(node->node->doc, node->node,
1981
- (xmlChar*)StringValuePtr(ns))));
1982
- }
1983
-
1984
-
1985
- /*
1986
- * call-seq:
1987
- * node.sibling(node) => node
1988
- *
1989
- * Add the specified node as a sibling of this node.
1990
- */
1991
- VALUE
1992
- ruby_xml_node_sibling_set(VALUE self, VALUE rnode) {
1993
- ruby_xml_node *cnode, *pnode;
1994
- xmlNodePtr ret;
1995
- VALUE obj;
1996
-
1997
- if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
1998
- rb_raise(rb_eTypeError, "Must pass an XML::Node object");
1999
-
2000
- Data_Get_Struct(self, ruby_xml_node, pnode);
2001
- Data_Get_Struct(rnode, ruby_xml_node, cnode);
2002
-
2003
- ret = xmlAddSibling(pnode->node, cnode->node);
2004
- if (ret == NULL)
2005
- rb_raise(eXMLNodeFailedModify, "unable to add a sibling to the document");
2006
- if (ret->_private==NULL)
2007
- obj=ruby_xml_node2_wrap(cXMLNode,ret);
2008
- else
2009
- obj=(VALUE)ret->_private;
2010
-
2011
- return obj;
2012
- }
2013
-
2014
-
2015
- /*
2016
- * call-seq:
2017
- * node.space_preserve => (true|false)
2018
- *
2019
- * Determine whether this node preserves whitespace.
2020
- */
2021
- VALUE
2022
- ruby_xml_node_space_preserve_get(VALUE self) {
2023
- ruby_xml_node *rxn;
2024
-
2025
- Data_Get_Struct(self, ruby_xml_node, rxn);
2026
- return(INT2NUM(xmlNodeGetSpacePreserve(rxn->node)));
2027
- }
2028
-
2029
-
2030
- /*
2031
- * call-seq:
2032
- * node.space_preserve = true|false
2033
- *
2034
- * Control whether this node preserves whitespace.
2035
- */
2036
- VALUE
2037
- ruby_xml_node_space_preserve_set(VALUE self, VALUE bool) {
2038
- ruby_xml_node *rxn;
2039
- Data_Get_Struct(self, ruby_xml_node, rxn);
2040
-
2041
- if (TYPE(bool) == T_FALSE)
2042
- xmlNodeSetSpacePreserve(rxn->node, 1);
2043
- else
2044
- xmlNodeSetSpacePreserve(rxn->node, 0);
2045
-
2046
- return(Qnil);
2047
- }
2048
-
2049
-
2050
- /*
2051
- * call-seq:
2052
- * node.text? => (true|false)
2053
- *
2054
- * Determine whether this node has text.
2055
- */
2056
- VALUE
2057
- ruby_xml_node_text_q(VALUE self) {
2058
- ruby_xml_node *rxn;
2059
- Data_Get_Struct(self, ruby_xml_node, rxn);
2060
- if (rxn->node == NULL)
2061
- return(Qnil);
2062
-
2063
- return((xmlNodeIsText(rxn->node) == 1) ? Qtrue : Qfalse);
2064
- }
2065
-
2066
-
2067
- /*
2068
- * call-seq:
2069
- * node.to_s => "string"
2070
- *
2071
- * Coerce this node to a string representation of
2072
- * it's XML.
2073
- */
2074
- VALUE
2075
- ruby_xml_node_to_s(VALUE self) {
2076
- ruby_xml_node *rxn;
2077
- xmlBufferPtr buf;
2078
- VALUE result;
2079
-
2080
- Data_Get_Struct(self, ruby_xml_node, rxn);
2081
- buf = xmlBufferCreate();
2082
- xmlNodeDump(buf, rxn->node->doc, rxn->node, 0, 1);
2083
- result = rb_str_new2((const char*)buf->content);
2084
-
2085
- xmlBufferFree(buf);
2086
- return result;
2087
- }
2088
-
2089
-
2090
- /*
2091
- * call-seq:
2092
- * node.type => num
2093
- *
2094
- * Obtain this node's type identifier.
2095
- */
2096
- VALUE
2097
- ruby_xml_node_type(VALUE self) {
2098
- ruby_xml_node *rxn;
2099
- Data_Get_Struct(self, ruby_xml_node, rxn);
2100
- return(INT2NUM(rxn->node->type));
2101
- }
2102
-
2103
-
2104
- /*
2105
- * call-seq:
2106
- * node.type_name => num
2107
- *
2108
- * Obtain this node's type name.
2109
- */
2110
- VALUE
2111
- ruby_xml_node_type_name(VALUE self) {
2112
- ruby_xml_node *rxn;
2113
- Data_Get_Struct(self, ruby_xml_node, rxn);
2114
-
2115
- switch(rxn->node->type) {
2116
- case XML_ELEMENT_NODE:
2117
- return(rb_str_new2("element"));
2118
- case XML_ATTRIBUTE_NODE:
2119
- return(rb_str_new2("attribute"));
2120
- case XML_TEXT_NODE:
2121
- return(rb_str_new2("text"));
2122
- case XML_CDATA_SECTION_NODE:
2123
- return(rb_str_new2("cdata"));
2124
- case XML_ENTITY_REF_NODE:
2125
- return(rb_str_new2("entity_ref"));
2126
- case XML_ENTITY_NODE:
2127
- return(rb_str_new2("entity"));
2128
- case XML_PI_NODE:
2129
- return(rb_str_new2("pi"));
2130
- case XML_COMMENT_NODE:
2131
- return(rb_str_new2("comment"));
2132
- case XML_DOCUMENT_NODE:
2133
- return(rb_str_new2("document_xml"));
2134
- case XML_DOCUMENT_TYPE_NODE:
2135
- return(rb_str_new2("doctype"));
2136
- case XML_DOCUMENT_FRAG_NODE:
2137
- return(rb_str_new2("fragment"));
2138
- case XML_NOTATION_NODE:
2139
- return(rb_str_new2("notation"));
2140
- case XML_HTML_DOCUMENT_NODE:
2141
- return(rb_str_new2("document_html"));
2142
- case XML_DTD_NODE:
2143
- return(rb_str_new2("dtd"));
2144
- case XML_ELEMENT_DECL:
2145
- return(rb_str_new2("elem_decl"));
2146
- case XML_ATTRIBUTE_DECL:
2147
- return(rb_str_new2("attribute_decl"));
2148
- case XML_ENTITY_DECL:
2149
- return(rb_str_new2("entity_decl"));
2150
- case XML_NAMESPACE_DECL:
2151
- return(rb_str_new2("namespace"));
2152
- case XML_XINCLUDE_START:
2153
- return(rb_str_new2("xinclude_start"));
2154
- case XML_XINCLUDE_END:
2155
- return(rb_str_new2("xinclude_end"));
2156
- #ifdef LIBXML_DOCB_ENABLED
2157
- case XML_DOCB_DOCUMENT_NODE:
2158
- return(rb_str_new2("document_docbook"));
2159
- #endif
2160
- default:
2161
- rb_raise(eXMLNodeUnknownType, "Unknown node type: %n", rxn->node->type);
2162
- return(Qfalse);
2163
- }
2164
- }
2165
-
2166
-
2167
- /*
2168
- * call-seq:
2169
- * node.xinclude_end? => num
2170
- *
2171
- * Determine whether this node is an xinclude end node.
2172
- */
2173
- VALUE
2174
- ruby_xml_node_xinclude_end_q(VALUE self) {
2175
- ruby_xml_node *rxn;
2176
- Data_Get_Struct(self, ruby_xml_node, rxn);
2177
- if (rxn->node->type == XML_XINCLUDE_END)
2178
- return(Qtrue);
2179
- else
2180
- return(Qfalse);
2181
- }
2182
-
2183
-
2184
- /*
2185
- * call-seq:
2186
- * node.xinclude_start? => num
2187
- *
2188
- * Determine whether this node is an xinclude start node.
2189
- */
2190
- VALUE
2191
- ruby_xml_node_xinclude_start_q(VALUE self) {
2192
- ruby_xml_node *rxn;
2193
- Data_Get_Struct(self, ruby_xml_node, rxn);
2194
- if (rxn->node->type == XML_XINCLUDE_START)
2195
- return(Qtrue);
2196
- else
2197
- return(Qfalse);
2198
- }
2199
-
2200
-
2201
- /*
2202
- * call-seq:
2203
- * node.copy => node
2204
- *
2205
- * Create a copy of this node.
2206
- */
2207
- VALUE
2208
- ruby_xml_node_copy(VALUE self, VALUE deep) {
2209
- ruby_xml_node *rxn;
2210
- xmlNode *copy;
2211
- VALUE obj;
2212
-
2213
- Data_Get_Struct(self, ruby_xml_node, rxn);
2214
- copy = xmlCopyNode( rxn->node, ((deep==Qnil)||(deep==Qfalse))?0:1 );
2215
-
2216
- if (copy == NULL)
2217
- return Qnil;
2218
-
2219
- obj=ruby_xml_node2_wrap(cXMLNode,copy);
2220
- copy->_private = (void*) obj;
2221
- return obj;
2222
- }
2223
-
2224
- /*
2225
- * call-seq:
2226
- * XML::Node.new_text(content = nil) => node
2227
- *
2228
- * Create a new text node, optionally setting
2229
- * the node's content.
2230
- *
2231
- */
2232
- VALUE
2233
- ruby_xml_node_new_text(VALUE class, VALUE text)
2234
- {
2235
- VALUE obj;
2236
- xmlNodePtr xnode;
2237
-
2238
- if ( NIL_P(text) )
2239
- return Qnil;
2240
-
2241
- if (TYPE(text) != T_STRING )
2242
- rb_raise(rb_eTypeError, "requires string argument");
2243
-
2244
- xnode=xmlNewText((xmlChar*)STR2CSTR(text));
2245
- if ( xnode == NULL )
2246
- return Qnil;
2247
-
2248
- obj=ruby_xml_node2_wrap(class,xnode);
2249
- rb_obj_call_init(obj,0,NULL);
2250
- return obj;
2251
- }
2252
-
2253
- void
2254
- ruby_xml_node_registerNode(xmlNodePtr node)
2255
- {
2256
- node->_private=NULL;
2257
- }
2258
-
2259
- void
2260
- ruby_xml_node_deregisterNode(xmlNodePtr node)
2261
- {
2262
- ruby_xml_node *rxn;
2263
- if ( node->_private==NULL ) return;
2264
- Data_Get_Struct(node->_private, ruby_xml_node, rxn);
2265
- rxn->node=NULL;
2266
- }
2267
-
2268
- // Rdoc needs to know
2269
- #ifdef RDOC_NEVER_DEFINED
2270
- mXML = rb_define_module("XML");
2271
- #endif
2272
-
2273
- void
2274
- ruby_init_xml_node(void) {
2275
- VALUE singleton;
2276
-
2277
- xmlRegisterNodeDefault(ruby_xml_node_registerNode);
2278
- xmlDeregisterNodeDefault(ruby_xml_node_deregisterNode);
2279
-
2280
- cXMLNode = rb_define_class_under(mXML, "Node", rb_cObject);
2281
- eXMLNodeSetNamespace = rb_define_class_under(cXMLNode, "SetNamespace", eXMLError);
2282
- eXMLNodeFailedModify = rb_define_class_under(cXMLNode, "FailedModify", eXMLError);
2283
- eXMLNodeUnknownType = rb_define_class_under(cXMLNode, "UnknownType", eXMLError);
2284
-
2285
- singleton = rb_singleton_class(cXMLNode);
2286
-
2287
- rb_define_const(cXMLNode, "SPACE_DEFAULT", INT2NUM(0));
2288
- rb_define_const(cXMLNode, "SPACE_PRESERVE", INT2NUM(1));
2289
- rb_define_const(cXMLNode, "SPACE_NOT_INHERIT", INT2NUM(-1));
2290
- rb_define_const(cXMLNode, "XLINK_ACTUATE_AUTO", INT2NUM(1));
2291
- rb_define_const(cXMLNode, "XLINK_ACTUATE_NONE", INT2NUM(0));
2292
- rb_define_const(cXMLNode, "XLINK_ACTUATE_ONREQUEST", INT2NUM(2));
2293
- rb_define_const(cXMLNode, "XLINK_SHOW_EMBED", INT2NUM(2));
2294
- rb_define_const(cXMLNode, "XLINK_SHOW_NEW", INT2NUM(1));
2295
- rb_define_const(cXMLNode, "XLINK_SHOW_NONE", INT2NUM(0));
2296
- rb_define_const(cXMLNode, "XLINK_SHOW_REPLACE", INT2NUM(3));
2297
- rb_define_const(cXMLNode, "XLINK_TYPE_EXTENDED", INT2NUM(2));
2298
- rb_define_const(cXMLNode, "XLINK_TYPE_EXTENDED_SET", INT2NUM(3));
2299
- rb_define_const(cXMLNode, "XLINK_TYPE_NONE", INT2NUM(0));
2300
- rb_define_const(cXMLNode, "XLINK_TYPE_SIMPLE", INT2NUM(1));
2301
-
2302
- rb_define_singleton_method(cXMLNode, "new2", ruby_xml_node2_new_native, 2);
2303
- rb_define_singleton_method(cXMLNode, "new", ruby_xml_node2_new_string_bc, -1);
2304
- rb_define_singleton_method(cXMLNode, "new_cdata", ruby_xml_node_new_cdata, -1);
2305
- rb_define_singleton_method(cXMLNode, "new_comment", ruby_xml_node_new_comment, -1);
2306
- rb_define_singleton_method(cXMLNode, "new_text", ruby_xml_node_new_text, 1);
2307
-
2308
- rb_define_alias(singleton, "new_element", "new");
2309
-
2310
- rb_define_method(cXMLNode, "<<", ruby_xml_node_content_add, 1);
2311
- rb_define_method(cXMLNode, "[]", ruby_xml_node_property_get, 1);
2312
- rb_define_method(cXMLNode, "[]=", ruby_xml_node_property_set, 2);
2313
- rb_define_method(cXMLNode, "attribute?", ruby_xml_node_attribute_q, 0);
2314
- rb_define_method(cXMLNode, "attribute_decl?", ruby_xml_node_attribute_decl_q, 0);
2315
- rb_define_method(cXMLNode, "base", ruby_xml_node_base_get, 0);
2316
- rb_define_method(cXMLNode, "base=", ruby_xml_node_base_set, 1);
2317
- rb_define_method(cXMLNode, "blank?", ruby_xml_node_empty_q, 0);
2318
- rb_define_method(cXMLNode, "cdata?", ruby_xml_node_cdata_q, 0);
2319
- rb_define_method(cXMLNode, "comment?", ruby_xml_node_comment_q, 0);
2320
- rb_define_method(cXMLNode, "copy", ruby_xml_node_copy, 1);
2321
- rb_define_method(cXMLNode, "child", ruby_xml_node_child_get, 0);
2322
- rb_define_method(cXMLNode, "child?", ruby_xml_node_child_q, 0);
2323
- rb_define_method(cXMLNode, "child=", ruby_xml_node_child_set, 1);
2324
- rb_define_method(cXMLNode, "child_add", ruby_xml_node_child_add, 1);
2325
- rb_define_method(cXMLNode, "children", ruby_xml_node_child_get, 0);
2326
- rb_define_method(cXMLNode, "children?", ruby_xml_node_child_q, 0);
2327
- rb_define_method(cXMLNode, "content", ruby_xml_node_content_get, 0);
2328
- rb_define_method(cXMLNode, "content=", ruby_xml_node_content_set, 1);
2329
- rb_define_method(cXMLNode, "content_stripped", ruby_xml_node_content_stripped_get, 0);
2330
- rb_define_method(cXMLNode, "doc", ruby_xml_node_doc, 0);
2331
- rb_define_method(cXMLNode, "docbook_doc?", ruby_xml_node_docbook_doc_q, 0);
2332
- rb_define_method(cXMLNode, "doctype?", ruby_xml_node_doctype_q, 0);
2333
- rb_define_method(cXMLNode, "document?", ruby_xml_node_document_q, 0);
2334
- rb_define_method(cXMLNode, "dtd?", ruby_xml_node_dtd_q, 0);
2335
- rb_define_method(cXMLNode, "dump", ruby_xml_node_dump, 0);
2336
- rb_define_method(cXMLNode, "debug_dump", ruby_xml_node_debug_dump, 0);
2337
- rb_define_method(cXMLNode, "element?", ruby_xml_node_element_q, 0);
2338
- rb_define_method(cXMLNode, "element_decl?", ruby_xml_node_element_decl_q, 0);
2339
- rb_define_method(cXMLNode, "empty?", ruby_xml_node_empty_q, 0);
2340
- rb_define_method(cXMLNode, "entity?", ruby_xml_node_entity_q, 0);
2341
- rb_define_method(cXMLNode, "entity_ref?", ruby_xml_node_entity_ref_q, 0);
2342
- rb_define_method(cXMLNode, "eql?", ruby_xml_node_eql_q, 1);
2343
- rb_define_method(cXMLNode, "find", ruby_xml_node_find, -1);
2344
- rb_define_method(cXMLNode, "find_first", ruby_xml_node_find_first, -1);
2345
- rb_define_method(cXMLNode, "fragment?", ruby_xml_node_fragment_q, 0);
2346
- rb_define_method(cXMLNode, "hash", ruby_xml_node_hash, 0);
2347
- rb_define_method(cXMLNode, "html_doc?", ruby_xml_node_html_doc_q, 0);
2348
- rb_define_method(cXMLNode, "lang", ruby_xml_node_lang_get, 0);
2349
- rb_define_method(cXMLNode, "lang=", ruby_xml_node_lang_set, 1);
2350
- rb_define_method(cXMLNode, "last", ruby_xml_node_last_get, 0);
2351
- rb_define_method(cXMLNode, "last?", ruby_xml_node_last_q, 0);
2352
- rb_define_method(cXMLNode, "line_num", ruby_xml_node_line_num, 0);
2353
- rb_define_method(cXMLNode, "name", ruby_xml_node_name_get, 0);
2354
- rb_define_method(cXMLNode, "name=", ruby_xml_node_name_set, 1);
2355
- rb_define_method(cXMLNode, "namespace", ruby_xml_node_namespace_get, 0);
2356
- rb_define_method(cXMLNode, "namespace_node", ruby_xml_node_namespace_get_node, 0);
2357
- rb_define_method(cXMLNode, "namespace?", ruby_xml_node_namespace_q, 0);
2358
- rb_define_method(cXMLNode, "namespace=", ruby_xml_node_namespace_set, -1);
2359
- rb_define_method(cXMLNode, "next", ruby_xml_node_next_get, 0);
2360
- rb_define_method(cXMLNode, "next?", ruby_xml_node_next_q, 0);
2361
- rb_define_method(cXMLNode, "next=", ruby_xml_node_next_set, 1);
2362
- rb_define_method(cXMLNode, "node_type", ruby_xml_node_type, 0);
2363
- rb_define_method(cXMLNode, "node_type_name", ruby_xml_node_type_name, 0);
2364
- rb_define_method(cXMLNode, "notation?", ruby_xml_node_notation_q, 0);
2365
- rb_define_method(cXMLNode, "ns", ruby_xml_node_namespace_get, 0);
2366
- rb_define_method(cXMLNode, "ns?", ruby_xml_node_ns_q, 0);
2367
- rb_define_method(cXMLNode, "ns_def", ruby_xml_node_ns_def_get, 0);
2368
- rb_define_method(cXMLNode, "ns_def?", ruby_xml_node_ns_def_q, 0);
2369
- rb_define_method(cXMLNode, "parent", ruby_xml_node_parent_get, 0);
2370
- rb_define_method(cXMLNode, "parent?", ruby_xml_node_parent_q, 0);
2371
- rb_define_method(cXMLNode, "path", ruby_xml_node_path, 0);
2372
- rb_define_method(cXMLNode, "pi?", ruby_xml_node_pi_q, 0);
2373
- rb_define_method(cXMLNode, "pointer", ruby_xml_node_pointer, 1);
2374
- rb_define_method(cXMLNode, "prev", ruby_xml_node_prev_get, 0);
2375
- rb_define_method(cXMLNode, "prev?", ruby_xml_node_prev_q, 0);
2376
- rb_define_method(cXMLNode, "prev=", ruby_xml_node_prev_set, 1);
2377
- rb_define_method(cXMLNode, "property", ruby_xml_node_property_get, 1);
2378
- rb_define_method(cXMLNode, "properties", ruby_xml_node_properties_get, 0);
2379
- rb_define_method(cXMLNode, "properties?", ruby_xml_node_properties_q, 0);
2380
- rb_define_method(cXMLNode, "remove!", ruby_xml_node_remove_ex, 0);
2381
- rb_define_method(cXMLNode, "search_ns", ruby_xml_node_search_ns, 1);
2382
- rb_define_method(cXMLNode, "search_href", ruby_xml_node_search_href, 1);
2383
- rb_define_method(cXMLNode, "sibling=", ruby_xml_node_sibling_set, 1);
2384
- rb_define_method(cXMLNode, "space_preserve", ruby_xml_node_space_preserve_get, 0);
2385
- rb_define_method(cXMLNode, "space_preserve=", ruby_xml_node_space_preserve_set, 1);
2386
- rb_define_method(cXMLNode, "text?", ruby_xml_node_text_q, 0);
2387
- rb_define_method(cXMLNode, "to_s", ruby_xml_node_to_s, 0);
2388
- rb_define_method(cXMLNode, "xinclude_end?", ruby_xml_node_xinclude_end_q, 0);
2389
- rb_define_method(cXMLNode, "xinclude_start?", ruby_xml_node_xinclude_start_q, 0);
2390
- rb_define_method(cXMLNode, "xlink?", ruby_xml_node_xlink_q, 0);
2391
- rb_define_method(cXMLNode, "xlink_type", ruby_xml_node_xlink_type, 0);
2392
- rb_define_method(cXMLNode, "xlink_type_name", ruby_xml_node_xlink_type_name, 0);
2393
-
2394
- rb_define_alias(cXMLNode, "==", "eql?");
2395
- }
1
+ /* $Id: ruby_xml_node.c 300 2008-07-01 19:14:15Z cfis $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ #include "ruby_libxml.h"
6
+ #include "ruby_xml_node.h"
7
+
8
+ VALUE cXMLNode;
9
+ VALUE eXMLNodeSetNamespace;
10
+ VALUE eXMLNodeFailedModify;
11
+ VALUE eXMLNodeUnknownType;
12
+
13
+ static VALUE
14
+ check_string_or_symbol( VALUE val ) {
15
+ if( TYPE(val) != T_STRING && TYPE(val) != T_SYMBOL ) {
16
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected String or Symbol)",
17
+ rb_obj_classname(val) );
18
+ }
19
+ return rb_obj_as_string( val );
20
+ }
21
+
22
+ /*
23
+ * call-seq:
24
+ * node.attribute? => (true|false)
25
+ *
26
+ * Determine whether this is an attribute node,
27
+ */
28
+ VALUE
29
+ ruby_xml_node_attribute_q(VALUE self) {
30
+ ruby_xml_node *rxn;
31
+ Data_Get_Struct(self, ruby_xml_node, rxn);
32
+ if (rxn->node->type == XML_ATTRIBUTE_NODE)
33
+ return(Qtrue);
34
+ else
35
+ return(Qfalse);
36
+ }
37
+
38
+
39
+ /*
40
+ * call-seq:
41
+ * node.attribute_decl? => (true|false)
42
+ *
43
+ * Determine whether this is an attribute declaration node,
44
+ */
45
+ VALUE
46
+ ruby_xml_node_attribute_decl_q(VALUE self) {
47
+ ruby_xml_node *rxn;
48
+ Data_Get_Struct(self, ruby_xml_node, rxn);
49
+ if (rxn->node->type == XML_ATTRIBUTE_DECL)
50
+ return(Qtrue);
51
+ else
52
+ return(Qfalse);
53
+ }
54
+
55
+
56
+ /*
57
+ * call-seq:
58
+ * node.base => "uri"
59
+ *
60
+ * Obtain this node's base URI.
61
+ */
62
+ VALUE
63
+ ruby_xml_node_base_get(VALUE self) {
64
+ ruby_xml_node *rxn;
65
+ xmlChar* base_uri;
66
+ VALUE result = Qnil;
67
+
68
+ Data_Get_Struct(self, ruby_xml_node, rxn);
69
+
70
+ if (rxn->node->doc == NULL)
71
+ return(result);
72
+
73
+ base_uri = xmlNodeGetBase(rxn->node->doc, rxn->node);
74
+ if (base_uri) {
75
+ result = rb_str_new2((const char*)base_uri);
76
+ xmlFree(base_uri);
77
+ }
78
+
79
+ return(result);
80
+ }
81
+
82
+
83
+ // TODO node_base_set should support setting back to nil
84
+
85
+ /*
86
+ * call-seq:
87
+ * node.base = "uri"
88
+ *
89
+ * Set this node's base URI.
90
+ */
91
+ VALUE
92
+ ruby_xml_node_base_set(VALUE self, VALUE uri) {
93
+ ruby_xml_node *node;
94
+
95
+ Check_Type(uri, T_STRING);
96
+ Data_Get_Struct(self, ruby_xml_node, node);
97
+ if (node->node->doc == NULL)
98
+ return(Qnil);
99
+
100
+ xmlNodeSetBase(node->node, (xmlChar*)StringValuePtr(uri));
101
+ return(Qtrue);
102
+ }
103
+
104
+
105
+ /*
106
+ * call-seq:
107
+ * node.cdata? => (true|false)
108
+ *
109
+ * Determine whether this is a #CDATA node
110
+ */
111
+ VALUE
112
+ ruby_xml_node_cdata_q(VALUE self) {
113
+ ruby_xml_node *rxn;
114
+ Data_Get_Struct(self, ruby_xml_node, rxn);
115
+ if (rxn->node->type == XML_CDATA_SECTION_NODE)
116
+ return(Qtrue);
117
+ else
118
+ return(Qfalse);
119
+ }
120
+
121
+
122
+ /*
123
+ * call-seq:
124
+ * node.comment? => (true|false)
125
+ *
126
+ * Determine whether this is a comment node
127
+ */
128
+ VALUE
129
+ ruby_xml_node_comment_q(VALUE self) {
130
+ ruby_xml_node *rxn;
131
+ Data_Get_Struct(self, ruby_xml_node, rxn);
132
+ if (rxn->node->type == XML_COMMENT_NODE)
133
+ return(Qtrue);
134
+ else
135
+ return(Qfalse);
136
+ }
137
+
138
+
139
+ /*
140
+ * call-seq:
141
+ * node << ("string" | node) => node
142
+ *
143
+ * Add the specified string or XML::Node to this node's
144
+ * content.
145
+ */
146
+ VALUE
147
+ ruby_xml_node_content_add(VALUE self, VALUE obj) {
148
+ ruby_xml_node *node;
149
+ VALUE str;
150
+
151
+ Data_Get_Struct(self, ruby_xml_node, node);
152
+ /* XXX This should only be legal for a CDATA type node, I think,
153
+ * resulting in a merge of content, as if a string were passed
154
+ * danj 070827
155
+ */
156
+ if (rb_obj_is_kind_of(obj, cXMLNode)) {
157
+ ruby_xml_node_child_set(self, obj);
158
+ return(self);
159
+ } else if (TYPE(obj) == T_STRING) {
160
+ xmlNodeAddContent(node->node, (xmlChar*)StringValuePtr(obj));
161
+ return(self);
162
+ } else {
163
+ str = rb_obj_as_string(obj);
164
+ if (NIL_P(str) || TYPE(str) != T_STRING)
165
+ rb_raise(rb_eTypeError, "invalid argument: must be string or XML::Node");
166
+
167
+ xmlNodeAddContent(node->node, (xmlChar*)StringValuePtr(str));
168
+ return(self);
169
+ }
170
+ }
171
+
172
+
173
+ /*
174
+ * call-seq:
175
+ * node.content => "string"
176
+ *
177
+ * Obtain this node's content as a string.
178
+ */
179
+ VALUE
180
+ ruby_xml_node_content_get(VALUE self) {
181
+ ruby_xml_node *rxn;
182
+ xmlChar *content;
183
+ VALUE result;
184
+
185
+ Data_Get_Struct(self, ruby_xml_node, rxn);
186
+ content = xmlNodeGetContent(rxn->node);
187
+ if (content) {
188
+ result = rb_str_new2((const char *) content);
189
+ xmlFree(content);
190
+ }
191
+
192
+ return result;
193
+ }
194
+
195
+ /*
196
+ * call-seq:
197
+ * node.content = "string"
198
+ *
199
+ * Set this node's content to the specified string.
200
+ */
201
+ VALUE
202
+ ruby_xml_node_content_set(VALUE self, VALUE content) {
203
+ ruby_xml_node *node;
204
+
205
+ Check_Type(content, T_STRING);
206
+ Data_Get_Struct(self, ruby_xml_node, node);
207
+ // XXX docs indicate need for escaping entites, need to be done? danj
208
+ xmlNodeSetContent(node->node, (xmlChar*)StringValuePtr(content));
209
+ return(Qtrue);
210
+ }
211
+
212
+
213
+ /*
214
+ * call-seq:
215
+ * node.content_stripped => "string"
216
+ *
217
+ * Obtain this node's stripped content.
218
+ *
219
+ * *Deprecated*: Stripped content can be obtained via the
220
+ * +content+ method.
221
+ */
222
+ VALUE
223
+ ruby_xml_node_content_stripped_get(VALUE self) {
224
+ ruby_xml_node *rxn;
225
+ xmlChar* content;
226
+ VALUE result = Qnil;
227
+
228
+ Data_Get_Struct(self, ruby_xml_node, rxn);
229
+
230
+ if (!rxn->node->content)
231
+ return result;
232
+
233
+ content = xmlNodeGetContent(rxn->node);
234
+ if (content) {
235
+ result = rb_str_new2((const char*)content);
236
+ xmlFree(content);
237
+ }
238
+ return(result);
239
+ }
240
+
241
+ /*
242
+ * call-seq:
243
+ * node.child => node
244
+ *
245
+ * Obtain this node's first child node, if any.
246
+ */
247
+ VALUE
248
+ ruby_xml_node_child_get(VALUE self) {
249
+ ruby_xml_node *node;
250
+ xmlNodePtr tmp;
251
+
252
+ Data_Get_Struct(self, ruby_xml_node, node);
253
+
254
+ switch (node->node->type) {
255
+ case XML_ELEMENT_NODE:
256
+ case XML_ENTITY_REF_NODE:
257
+ case XML_ENTITY_NODE:
258
+ case XML_PI_NODE:
259
+ case XML_COMMENT_NODE:
260
+ case XML_DOCUMENT_NODE:
261
+ #ifdef LIBXML_DOCB_ENABLED
262
+ case XML_DOCB_DOCUMENT_NODE:
263
+ #endif
264
+ case XML_HTML_DOCUMENT_NODE:
265
+ case XML_DTD_NODE:
266
+ tmp = node->node->children;
267
+ break;
268
+ case XML_ATTRIBUTE_NODE:
269
+ {
270
+ xmlAttrPtr attr = (xmlAttrPtr) node->node;
271
+ tmp = attr->children;
272
+ break;
273
+ }
274
+ default:
275
+ tmp = NULL;
276
+ break;
277
+ }
278
+
279
+ if (tmp == NULL)
280
+ return(Qnil);
281
+ else
282
+ return(ruby_xml_node2_wrap(cXMLNode, tmp));
283
+ }
284
+
285
+
286
+ /*
287
+ * call-seq:
288
+ * node.child? => (true|false)
289
+ *
290
+ * Determine whether this node has at least one child.
291
+ */
292
+ VALUE
293
+ ruby_xml_node_child_q(VALUE self) {
294
+ ruby_xml_node *rxn;
295
+ xmlNodePtr node;
296
+ Data_Get_Struct(self, ruby_xml_node, rxn);
297
+
298
+ node = NULL;
299
+ switch (rxn->node->type) {
300
+ case XML_ELEMENT_NODE:
301
+ case XML_ENTITY_REF_NODE:
302
+ case XML_ENTITY_NODE:
303
+ case XML_PI_NODE:
304
+ case XML_COMMENT_NODE:
305
+ case XML_DOCUMENT_NODE:
306
+ #ifdef LIBXML_DOCB_ENABLED
307
+ case XML_DOCB_DOCUMENT_NODE:
308
+ #endif
309
+ case XML_HTML_DOCUMENT_NODE:
310
+ case XML_DTD_NODE:
311
+ node = rxn->node->children;
312
+ break;
313
+ case XML_ATTRIBUTE_NODE:
314
+ {
315
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
316
+ node = attr->children;
317
+ break;
318
+ }
319
+ default:
320
+ node = NULL;
321
+ }
322
+
323
+ if (node == NULL)
324
+ return(Qfalse);
325
+ else
326
+ return(Qtrue);
327
+ }
328
+
329
+ /*
330
+ * underlying for child_set and child_add, difference being
331
+ * former raises on implicit copy, latter does not.
332
+ */
333
+ VALUE
334
+ ruby_xml_node_child_set_aux(VALUE self, VALUE rnode, int do_raise) {
335
+ ruby_xml_node *cnode, *pnode;
336
+ xmlNodePtr chld, ret;
337
+ int copied=0;
338
+
339
+ if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
340
+ rb_raise(rb_eTypeError, "Must pass an XML::Node object");
341
+
342
+ Data_Get_Struct(self, ruby_xml_node, pnode);
343
+ Data_Get_Struct(rnode, ruby_xml_node, cnode);
344
+
345
+ chld = cnode->node;
346
+ /* Since an add operation may destroy a textnode by merging, we need to work
347
+ * with a copy, so that the ruby instance is not left with a dangling reference
348
+ */
349
+ if ( chld->type == XML_TEXT_NODE ) {
350
+ chld = xmlCopyNode(chld,1);
351
+ copied=1;
352
+ }
353
+
354
+ if ( chld->parent != NULL || chld->doc != NULL ) {
355
+ /* raise before copying if applicable */
356
+ if ( do_raise == 1 )
357
+ rb_raise(rb_eRuntimeError, "implicit copy not legal for child= or <<");
358
+ chld=xmlCopyNode(chld,1);
359
+ copied=1;
360
+ }
361
+
362
+ ret = xmlAddChild(pnode->node, chld);
363
+ if (ret == NULL) {
364
+ if ( copied == 1 )
365
+ xmlFreeNode(chld);
366
+ rb_raise(eXMLNodeFailedModify, "unable to add a child to the document");
367
+ } else if ( ret==chld ) {
368
+ /* child was added whole to parent and we need to return it as a new object */
369
+ return ruby_xml_node2_wrap(cXMLNode,chld);
370
+ }
371
+ /* else */
372
+ /* If it was a text node, then ret should be parent->last, so we will just return ret. */
373
+ return ruby_xml_node2_wrap(cXMLNode,ret);
374
+ }
375
+
376
+ /*
377
+ * call-seq:
378
+ * node.child = node
379
+ *
380
+ * Set a child node for this node. Also called for <<
381
+ */
382
+ VALUE
383
+ ruby_xml_node_child_set(VALUE self, VALUE rnode) {
384
+ return ruby_xml_node_child_set_aux(self,rnode,1);
385
+ }
386
+
387
+ /*
388
+ * call-seq:
389
+ * node.child_add(node)
390
+ *
391
+ * Set a child node for this node.
392
+ */
393
+ VALUE
394
+ ruby_xml_node_child_add(VALUE self, VALUE rnode) {
395
+ return ruby_xml_node_child_set_aux(self,rnode,0);
396
+ }
397
+
398
+ /*
399
+ * call-seq:
400
+ * node.doc => document
401
+ *
402
+ * Obtain the XML::Document this node belongs to.
403
+ */
404
+ VALUE
405
+ ruby_xml_node_doc(VALUE self) {
406
+ ruby_xml_node *rxn;
407
+ xmlDocPtr doc=NULL;
408
+
409
+ Data_Get_Struct(self, ruby_xml_node, rxn);
410
+
411
+ switch (rxn->node->type) {
412
+ case XML_DOCUMENT_NODE:
413
+ #ifdef LIBXML_DOCB_ENABLED
414
+ case XML_DOCB_DOCUMENT_NODE:
415
+ #endif
416
+ case XML_HTML_DOCUMENT_NODE:
417
+ doc = NULL;
418
+ break;
419
+ case XML_ATTRIBUTE_NODE:
420
+ {
421
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
422
+ doc = attr->doc;
423
+ break;
424
+ }
425
+ case XML_NAMESPACE_DECL:
426
+ doc = NULL;
427
+ break;
428
+ default:
429
+ doc = rxn->node->doc;
430
+ break;
431
+ }
432
+
433
+ if (doc == NULL)
434
+ return(Qnil);
435
+
436
+ if ( doc->_private == NULL )
437
+ rb_raise(rb_eRuntimeError,"existing document object has no ruby-instance");
438
+
439
+ return (VALUE)doc->_private;
440
+ }
441
+
442
+
443
+ /*
444
+ * call-seq:
445
+ * node.docbook? => (true|false)
446
+ *
447
+ * Determine whether this is a docbook node.
448
+ */
449
+ VALUE
450
+ ruby_xml_node_docbook_doc_q(VALUE self) {
451
+ #ifdef LIBXML_DOCB_ENABLED
452
+ ruby_xml_node *rxn;
453
+ Data_Get_Struct(self, ruby_xml_node, rxn);
454
+ if (rxn->node->type == XML_DOCB_DOCUMENT_NODE)
455
+ return(Qtrue);
456
+ else
457
+ return(Qfalse);
458
+ #else
459
+ rb_warn("libxml compiled without docbook support");
460
+ return(Qfalse);
461
+ #endif
462
+ }
463
+
464
+
465
+ /*
466
+ * call-seq:
467
+ * node.doctype? => (true|false)
468
+ *
469
+ * Determine whether this is a DOCTYPE node.
470
+ */
471
+ VALUE
472
+ ruby_xml_node_doctype_q(VALUE self) {
473
+ ruby_xml_node *rxn;
474
+ Data_Get_Struct(self, ruby_xml_node, rxn);
475
+ if (rxn->node->type == XML_DOCUMENT_TYPE_NODE)
476
+ return(Qtrue);
477
+ else
478
+ return(Qfalse);
479
+ }
480
+
481
+
482
+ /*
483
+ * call-seq:
484
+ * node.document? => (true|false)
485
+ *
486
+ * Determine whether this is a document node.
487
+ */
488
+ VALUE
489
+ ruby_xml_node_document_q(VALUE self) {
490
+ ruby_xml_node *rxn;
491
+ Data_Get_Struct(self, ruby_xml_node, rxn);
492
+ if (rxn->node->type == XML_DOCUMENT_NODE)
493
+ return(Qtrue);
494
+ else
495
+ return(Qfalse);
496
+ }
497
+
498
+
499
+ /*
500
+ * call-seq:
501
+ * node.dtd? => (true|false)
502
+ *
503
+ * Determine whether this is a DTD node.
504
+ */
505
+ VALUE
506
+ ruby_xml_node_dtd_q(VALUE self) {
507
+ ruby_xml_node *rxn;
508
+ Data_Get_Struct(self, ruby_xml_node, rxn);
509
+ if (rxn->node->type == XML_DTD_NODE)
510
+ return(Qtrue);
511
+ else
512
+ return(Qfalse);
513
+ }
514
+
515
+
516
+ /*
517
+ * call-seq:
518
+ * node.dump => (true|nil)
519
+ *
520
+ * Dump this node to stdout.
521
+ */
522
+ VALUE
523
+ ruby_xml_node_dump(VALUE self) {
524
+ ruby_xml_node *rxn;
525
+ xmlBufferPtr buf;
526
+
527
+ Data_Get_Struct(self, ruby_xml_node, rxn);
528
+
529
+ if (rxn->node->doc == NULL)
530
+ return(Qnil);
531
+
532
+ buf = xmlBufferCreate();
533
+ xmlNodeDump(buf, rxn->node->doc, rxn->node, 0, 1);
534
+ xmlBufferDump(stdout, buf);
535
+ xmlBufferFree(buf);
536
+ return(Qtrue);
537
+ }
538
+
539
+
540
+ /*
541
+ * call-seq:
542
+ * node.debug_dump => (true|nil)
543
+ *
544
+ * Dump this node to stdout, including any debugging
545
+ * information.
546
+ */
547
+ VALUE
548
+ ruby_xml_node_debug_dump(VALUE self) {
549
+ ruby_xml_node *rxn;
550
+ Data_Get_Struct(self, ruby_xml_node, rxn);
551
+
552
+ if (rxn->node->doc == NULL)
553
+ return(Qnil);
554
+
555
+ xmlElemDump(stdout, rxn->node->doc, rxn->node);
556
+ return(Qtrue);
557
+ }
558
+
559
+
560
+ /*
561
+ * call-seq:
562
+ * node.element? => (true|false)
563
+ *
564
+ * Determine whether this is an element node.
565
+ */
566
+ VALUE
567
+ ruby_xml_node_element_q(VALUE self) {
568
+ ruby_xml_node *rxn;
569
+ Data_Get_Struct(self, ruby_xml_node, rxn);
570
+ if (rxn->node->type == XML_ELEMENT_NODE)
571
+ return(Qtrue);
572
+ else
573
+ return(Qfalse);
574
+ }
575
+
576
+
577
+ /*
578
+ * call-seq:
579
+ * node.element_decl? => (true|false)
580
+ *
581
+ * Determine whether this is an element declaration node.
582
+ */
583
+ VALUE
584
+ ruby_xml_node_element_decl_q(VALUE self) {
585
+ ruby_xml_node *rxn;
586
+ Data_Get_Struct(self, ruby_xml_node, rxn);
587
+ if (rxn->node->type == XML_ELEMENT_DECL)
588
+ return(Qtrue);
589
+ else
590
+ return(Qfalse);
591
+ }
592
+
593
+
594
+ /*
595
+ * call-seq:
596
+ * node.empty? => (true|false)
597
+ *
598
+ * Determine whether this node is empty.
599
+ */
600
+ VALUE
601
+ ruby_xml_node_empty_q(VALUE self) {
602
+ ruby_xml_node *rxn;
603
+ Data_Get_Struct(self, ruby_xml_node, rxn);
604
+ if (rxn->node == NULL)
605
+ return(Qnil);
606
+
607
+ return((xmlIsBlankNode(rxn->node) == 1) ? Qtrue : Qfalse);
608
+ }
609
+
610
+
611
+ /*
612
+ * call-seq:
613
+ * node.entity? => (true|false)
614
+ *
615
+ * Determine whether this is an entity node.
616
+ */
617
+ VALUE
618
+ ruby_xml_node_entity_q(VALUE self) {
619
+ ruby_xml_node *rxn;
620
+ Data_Get_Struct(self, ruby_xml_node, rxn);
621
+ if (rxn->node->type == XML_ENTITY_NODE)
622
+ return(Qtrue);
623
+ else
624
+ return(Qfalse);
625
+ }
626
+
627
+
628
+ /*
629
+ * call-seq:
630
+ * node.entity_ref? => (true|false)
631
+ *
632
+ * Determine whether this is an entity reference node.
633
+ */
634
+ VALUE
635
+ ruby_xml_node_entity_ref_q(VALUE self) {
636
+ ruby_xml_node *rxn;
637
+ Data_Get_Struct(self, ruby_xml_node, rxn);
638
+ if (rxn->node->type == XML_ENTITY_REF_NODE)
639
+ return(Qtrue);
640
+ else
641
+ return(Qfalse);
642
+ }
643
+
644
+ VALUE ruby_xml_node_to_s(VALUE self);
645
+
646
+ /*
647
+ * call-seq:
648
+ * node.eql?(other_node) => (true|false)
649
+ *
650
+ * Test equality between the two nodes. Equality is determined based
651
+ * on the XML representation of the nodes.
652
+ */
653
+ VALUE
654
+ ruby_xml_node_eql_q(VALUE self, VALUE other) {
655
+ // TODO this isn't the best way to handle this
656
+ ruby_xml_node *rxn, *orxn;
657
+ VALUE thisxml, otherxml;
658
+ Data_Get_Struct(self, ruby_xml_node, rxn);
659
+ Data_Get_Struct(other, ruby_xml_node, orxn);
660
+ thisxml = ruby_xml_node_to_s(self);
661
+ otherxml = ruby_xml_node_to_s(other);
662
+
663
+ return(rb_funcall(thisxml, rb_intern("=="), 1, otherxml));
664
+ }
665
+
666
+
667
+ /*
668
+ * call-seq:
669
+ * node.find(xpath_expr, namespace = [any]) => nodeset
670
+ *
671
+ * Find nodes matching the specified xpath expression, optionally
672
+ * using the specified namespaces. Returns an XML::Node::Set.
673
+ */
674
+ VALUE
675
+ ruby_xml_node_find(int argc, VALUE *argv, VALUE self) {
676
+ if (argc > 2 || argc < 1)
677
+ rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
678
+
679
+ return(ruby_xml_xpath_find2(self,argv[0],(argc==2)?argv[1]:Qnil));
680
+ }
681
+
682
+ /*
683
+ * call-seq:
684
+ * node.find_first(xpath_expr, namespace = [any]) => nodeset
685
+ *
686
+ * Find the first node matching the specified xpath expression, optionally
687
+ * using the specified namespaces. Returns an XML::Node.
688
+ */
689
+ VALUE
690
+ ruby_xml_node_find_first(int argc, VALUE *argv, VALUE self) {
691
+ return ruby_xml_xpath_object_first(ruby_xml_node_find(argc, argv, self));
692
+ }
693
+
694
+
695
+ /*
696
+ * call-seq:
697
+ * node.fragment? => (true|false)
698
+ *
699
+ * Determine whether this node is a fragment.
700
+ */
701
+ VALUE
702
+ ruby_xml_node_fragment_q(VALUE self) {
703
+ ruby_xml_node *rxn;
704
+ Data_Get_Struct(self, ruby_xml_node, rxn);
705
+ if (rxn->node->type == XML_DOCUMENT_FRAG_NODE)
706
+ return(Qtrue);
707
+ else
708
+ return(Qfalse);
709
+ }
710
+
711
+ /*
712
+ * call-seq:
713
+ * node.hash => fixnum
714
+ *
715
+ * Returns the hash-code for this node. This is the hash of the XML
716
+ * representation in order to be consistent with eql.
717
+ */
718
+ VALUE
719
+ ruby_xml_node_hash(VALUE self) {
720
+ ruby_xml_node *rxn;
721
+ VALUE thisxml;
722
+ Data_Get_Struct(self, ruby_xml_node, rxn);
723
+ thisxml = ruby_xml_node_to_s(self);
724
+
725
+ return(rb_funcall(thisxml, rb_intern("hash"), 0));
726
+ }
727
+
728
+
729
+ /*
730
+ * call-seq:
731
+ * node.html_doc? => (true|false)
732
+ *
733
+ * Determine whether this node is an html document node.
734
+ */
735
+ VALUE
736
+ ruby_xml_node_html_doc_q(VALUE self) {
737
+ ruby_xml_node *rxn;
738
+ Data_Get_Struct(self, ruby_xml_node, rxn);
739
+ if (rxn->node->type == XML_HTML_DOCUMENT_NODE)
740
+ return(Qtrue);
741
+ else
742
+ return(Qfalse);
743
+ }
744
+
745
+ /*
746
+ * call-seq:
747
+ * XML::Node.new_cdata(content = nil) => node
748
+ *
749
+ * Create a new #CDATA node, optionally setting
750
+ * the node's content.
751
+ */
752
+ VALUE
753
+ ruby_xml_node_new_cdata(int argc, VALUE *argv, VALUE class) {
754
+ xmlNodePtr xnode;
755
+ VALUE str=Qnil;
756
+
757
+ switch(argc) {
758
+ case 1:
759
+ str = argv[0];
760
+ Check_Type(str, T_STRING);
761
+ if (!NIL_P(str)) {
762
+ xnode = xmlNewCDataBlock(NULL, (xmlChar*)StringValuePtr(str), xmlStrlen((xmlChar*)StringValuePtr(str)));
763
+ } else {
764
+ xnode = xmlNewCDataBlock(NULL, NULL , 0);
765
+ }
766
+
767
+ if (xnode == NULL)
768
+ return(Qnil);
769
+
770
+ return ruby_xml_node2_wrap(class,xnode);
771
+
772
+ default:
773
+ rb_raise(rb_eArgError, "wrong number of arguments (1)");
774
+ }
775
+
776
+ // not reached
777
+ return(Qnil);
778
+ }
779
+
780
+
781
+ /*
782
+ * call-seq:
783
+ * XML::Node.new_comment(content = nil) => node
784
+ *
785
+ * Create a new comment node, optionally setting
786
+ * the node's content.
787
+ *
788
+ */
789
+ VALUE
790
+ ruby_xml_node_new_comment(int argc, VALUE *argv, VALUE class) {
791
+ xmlNodePtr xnode;
792
+ VALUE str=Qnil;
793
+
794
+ switch(argc) {
795
+ case 1:
796
+ str = argv[0];
797
+ Check_Type(str, T_STRING);
798
+ // TODO xmlNewComment wrongly? adds \n before and after the comment
799
+ if (!NIL_P(str)) {
800
+ xnode = xmlNewComment((xmlChar*)StringValuePtr(str));
801
+ } else {
802
+ xnode = xmlNewComment(NULL);
803
+ }
804
+
805
+ if (xnode == NULL)
806
+ return(Qnil);
807
+
808
+ return ruby_xml_node2_wrap(class,xnode);
809
+
810
+ default:
811
+ rb_raise(rb_eArgError, "wrong number of arguments (1)");
812
+ }
813
+
814
+ // not reached
815
+ return(Qnil);
816
+ }
817
+
818
+
819
+ /*
820
+ * call-seq:
821
+ * node.lang => "string"
822
+ *
823
+ * Obtain the language set for this node, if any.
824
+ * This is set in XML via the xml:lang attribute.
825
+ */
826
+ VALUE
827
+ ruby_xml_node_lang_get(VALUE self) {
828
+ ruby_xml_node *rxn;
829
+ xmlChar *lang;
830
+ VALUE result = Qnil;
831
+
832
+ Data_Get_Struct(self, ruby_xml_node, rxn);
833
+ lang = xmlNodeGetLang(rxn->node);
834
+
835
+ if (lang) {
836
+ result = rb_str_new2((const char*)lang);
837
+ xmlFree(lang);
838
+ }
839
+
840
+ return(result);
841
+ }
842
+
843
+
844
+ // TODO node_lang_set should support setting back to nil
845
+
846
+ /*
847
+ * call-seq:
848
+ * node.lang = "string"
849
+ *
850
+ * Set the language for this node. This affects the value
851
+ * of the xml:lang attribute.
852
+ */
853
+ VALUE
854
+ ruby_xml_node_lang_set(VALUE self, VALUE lang) {
855
+ ruby_xml_node *node;
856
+
857
+ Check_Type(lang, T_STRING);
858
+ Data_Get_Struct(self, ruby_xml_node, node);
859
+ xmlNodeSetLang(node->node, (xmlChar*)StringValuePtr(lang));
860
+
861
+ return(Qtrue);
862
+ }
863
+
864
+
865
+ /*
866
+ * call-seq:
867
+ * node.last => node
868
+ *
869
+ * Obtain the last child node of this node, if any.
870
+ */
871
+ VALUE
872
+ ruby_xml_node_last_get(VALUE self) {
873
+ ruby_xml_node *rxn;
874
+ xmlNodePtr node;
875
+
876
+ Data_Get_Struct(self, ruby_xml_node, rxn);
877
+
878
+ switch (rxn->node->type) {
879
+ case XML_ELEMENT_NODE:
880
+ case XML_ENTITY_REF_NODE:
881
+ case XML_ENTITY_NODE:
882
+ case XML_PI_NODE:
883
+ case XML_COMMENT_NODE:
884
+ case XML_DOCUMENT_NODE:
885
+ #ifdef LIBXML_DOCB_ENABLED
886
+ case XML_DOCB_DOCUMENT_NODE:
887
+ #endif
888
+ case XML_HTML_DOCUMENT_NODE:
889
+ case XML_DTD_NODE:
890
+ node = rxn->node->last;
891
+ break;
892
+ case XML_ATTRIBUTE_NODE:
893
+ {
894
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
895
+ node = attr->last;
896
+ }
897
+ default:
898
+ node = NULL;
899
+ break;
900
+ }
901
+
902
+ if (node == NULL)
903
+ return(Qnil);
904
+ else
905
+ return(ruby_xml_node2_wrap(cXMLNode, node));
906
+ }
907
+
908
+
909
+ /*
910
+ * call-seq:
911
+ * node.last? => (true|false)
912
+ *
913
+ * Determine whether this node has a last child node.
914
+ */
915
+ VALUE
916
+ ruby_xml_node_last_q(VALUE self) {
917
+ ruby_xml_node *rxn;
918
+ xmlNodePtr node;
919
+
920
+ Data_Get_Struct(self, ruby_xml_node, rxn);
921
+
922
+ switch (rxn->node->type) {
923
+ case XML_ELEMENT_NODE:
924
+ case XML_ENTITY_REF_NODE:
925
+ case XML_ENTITY_NODE:
926
+ case XML_PI_NODE:
927
+ case XML_COMMENT_NODE:
928
+ case XML_DOCUMENT_NODE:
929
+ #ifdef LIBXML_DOCB_ENABLED
930
+ case XML_DOCB_DOCUMENT_NODE:
931
+ #endif
932
+ case XML_HTML_DOCUMENT_NODE:
933
+ case XML_DTD_NODE:
934
+ node = rxn->node->last;
935
+ break;
936
+ case XML_ATTRIBUTE_NODE:
937
+ {
938
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
939
+ node = attr->last;
940
+ }
941
+ default:
942
+ node = NULL;
943
+ break;
944
+ }
945
+
946
+ if (node == NULL)
947
+ return(Qfalse);
948
+ else
949
+ return(Qtrue);
950
+ }
951
+
952
+
953
+ /*
954
+ * call-seq:
955
+ * node.line_num => num
956
+ *
957
+ * Obtain the line number (in the XML document) that this
958
+ * node was read from. If +default_line_numbers+ is set
959
+ * false (the default), this method returns zero.
960
+ */
961
+ VALUE
962
+ ruby_xml_node_line_num(VALUE self) {
963
+ ruby_xml_node *rxn;
964
+ long line_num;
965
+ Data_Get_Struct(self, ruby_xml_node, rxn);
966
+
967
+ if (!xmlLineNumbersDefaultValue)
968
+ rb_warn("Line numbers were not retained: use XML::Parser::default_line_numbers=true");
969
+
970
+ line_num = xmlGetLineNo(rxn->node);
971
+ if (line_num == -1)
972
+ return(Qnil);
973
+ else
974
+ return(INT2NUM((long)line_num));
975
+ }
976
+
977
+
978
+ /*
979
+ * call-seq:
980
+ * node.xlink? => (true|false)
981
+ *
982
+ * Determine whether this node is an xlink node.
983
+ */
984
+ VALUE
985
+ ruby_xml_node_xlink_q(VALUE self) {
986
+ ruby_xml_node *node;
987
+ xlinkType xlt;
988
+
989
+ Data_Get_Struct(self, ruby_xml_node, node);
990
+ xlt = xlinkIsLink(node->node->doc, node->node);
991
+
992
+ if (xlt == XLINK_TYPE_NONE)
993
+ return(Qfalse);
994
+ else
995
+ return(Qtrue);
996
+ }
997
+
998
+
999
+ /*
1000
+ * call-seq:
1001
+ * node.xlink_type => num
1002
+ *
1003
+ * Obtain the type identifier for this xlink, if applicable.
1004
+ * If this is not an xlink node (see +xlink?+), will return
1005
+ * nil.
1006
+ */
1007
+ VALUE
1008
+ ruby_xml_node_xlink_type(VALUE self) {
1009
+ ruby_xml_node *node;
1010
+ xlinkType xlt;
1011
+
1012
+ Data_Get_Struct(self, ruby_xml_node, node);
1013
+ xlt = xlinkIsLink(node->node->doc, node->node);
1014
+
1015
+ if (xlt == XLINK_TYPE_NONE)
1016
+ return(Qnil);
1017
+ else
1018
+ return(INT2NUM(xlt));
1019
+ }
1020
+
1021
+
1022
+ /*
1023
+ * call-seq:
1024
+ * node.xlink_type_name => "string"
1025
+ *
1026
+ * Obtain the type name for this xlink, if applicable.
1027
+ * If this is not an xlink node (see +xlink?+), will return
1028
+ * nil.
1029
+ */
1030
+ VALUE
1031
+ ruby_xml_node_xlink_type_name(VALUE self) {
1032
+ ruby_xml_node *node;
1033
+ xlinkType xlt;
1034
+
1035
+ Data_Get_Struct(self, ruby_xml_node, node);
1036
+ xlt = xlinkIsLink(node->node->doc, node->node);
1037
+
1038
+ switch(xlt) {
1039
+ case XLINK_TYPE_NONE:
1040
+ return(Qnil);
1041
+ case XLINK_TYPE_SIMPLE:
1042
+ return(rb_str_new2("simple"));
1043
+ case XLINK_TYPE_EXTENDED:
1044
+ return(rb_str_new2("extended"));
1045
+ case XLINK_TYPE_EXTENDED_SET:
1046
+ return(rb_str_new2("extended_set"));
1047
+ default:
1048
+ rb_fatal("Unknowng xlink type, %d", xlt);
1049
+ }
1050
+ }
1051
+
1052
+ /*
1053
+ * call-seq:
1054
+ * node.name => "string"
1055
+ *
1056
+ * Obtain this node's name.
1057
+ */
1058
+ VALUE
1059
+ ruby_xml_node_name_get(VALUE self) {
1060
+ ruby_xml_node *rxn;
1061
+ const xmlChar *name;
1062
+
1063
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1064
+
1065
+ switch (rxn->node->type) {
1066
+ case XML_DOCUMENT_NODE:
1067
+ #ifdef LIBXML_DOCB_ENABLED
1068
+ case XML_DOCB_DOCUMENT_NODE:
1069
+ #endif
1070
+ case XML_HTML_DOCUMENT_NODE:
1071
+ {
1072
+ xmlDocPtr doc = (xmlDocPtr) rxn->node;
1073
+ name = doc->URL;
1074
+ break;
1075
+ }
1076
+ case XML_ATTRIBUTE_NODE:
1077
+ {
1078
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1079
+ name = attr->name;
1080
+ break;
1081
+ }
1082
+ case XML_NAMESPACE_DECL:
1083
+ {
1084
+ xmlNsPtr ns = (xmlNsPtr) rxn->node;
1085
+ name = ns->prefix;
1086
+ break;
1087
+ }
1088
+ default:
1089
+ name = rxn->node->name;
1090
+ break;
1091
+ }
1092
+
1093
+ if (rxn->node->name == NULL)
1094
+ return(Qnil);
1095
+ else
1096
+ return(rb_str_new2((const char*)name));
1097
+ }
1098
+
1099
+
1100
+ /*
1101
+ * call-seq:
1102
+ * node.name = "string"
1103
+ *
1104
+ * Set this node's name.
1105
+ */
1106
+ VALUE
1107
+ ruby_xml_node_name_set(VALUE self, VALUE name) {
1108
+ ruby_xml_node *node;
1109
+
1110
+ Check_Type(name, T_STRING);
1111
+ Data_Get_Struct(self, ruby_xml_node, node);
1112
+ xmlNodeSetName(node->node, (xmlChar*)StringValuePtr(name));
1113
+ return(Qtrue);
1114
+ }
1115
+
1116
+
1117
+ /*
1118
+ * call-seq:
1119
+ * node.namespace => [namespace, ..., namespace]
1120
+ *
1121
+ * Obtain an array of +XML::NS+ objects representing
1122
+ * this node's xmlns attributes
1123
+ */
1124
+ VALUE
1125
+ ruby_xml_node_namespace_get(VALUE self) {
1126
+ ruby_xml_node *node;
1127
+ xmlNsPtr *nsList, *cur;
1128
+ VALUE arr, ns;
1129
+
1130
+ Data_Get_Struct(self, ruby_xml_node, node);
1131
+ if (node->node == NULL)
1132
+ return(Qnil);
1133
+
1134
+ nsList = xmlGetNsList(node->node->doc, node->node);
1135
+
1136
+ if (nsList == NULL)
1137
+ return(Qnil);
1138
+
1139
+ arr = rb_ary_new();
1140
+ for (cur = nsList; *cur != NULL; cur++) {
1141
+ ns = ruby_xml_ns_new2(cXMLNS, ruby_xml_document_wrap(node->node->doc), *cur);
1142
+ if (ns == Qnil)
1143
+ continue;
1144
+ else
1145
+ rb_ary_push(arr, ns);
1146
+ }
1147
+ xmlFree(nsList);
1148
+
1149
+ return(arr);
1150
+ }
1151
+
1152
+
1153
+ /*
1154
+ * call-seq:
1155
+ * node.namespace_node => namespace.
1156
+ *
1157
+ * Obtain this node's namespace node.
1158
+ */
1159
+ VALUE
1160
+ ruby_xml_node_namespace_get_node(VALUE self) {
1161
+ ruby_xml_node *node;
1162
+
1163
+ Data_Get_Struct(self, ruby_xml_node, node);
1164
+ if (node->node->ns == NULL)
1165
+ return(Qnil);
1166
+ else
1167
+ return ruby_xml_ns_new2(cXMLNS,
1168
+ ruby_xml_document_wrap(node->node->doc),
1169
+ node->node->ns);
1170
+ }
1171
+
1172
+ // TODO namespace_set can take varargs (in fact, must if used
1173
+ // with strings), but I cannot see how you can call
1174
+ // that version, apart from with 'send'
1175
+ //
1176
+ // Would sure be nice to support foo.namespace['foo'] = 'bar'
1177
+ // but maybe that's not practical...
1178
+
1179
+ /*
1180
+ * call-seq:
1181
+ * node.namespace = namespace
1182
+ *
1183
+ * Add the specified XML::NS object to this node's xmlns attributes.
1184
+ */
1185
+ VALUE
1186
+ ruby_xml_node_namespace_set(int argc, VALUE *argv, VALUE self) {
1187
+ VALUE rns, rprefix;
1188
+ ruby_xml_node *rxn;
1189
+ ruby_xml_ns *rxns;
1190
+ xmlNsPtr ns;
1191
+ char *cp, *href;
1192
+
1193
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1194
+ switch (argc) {
1195
+ case 1:
1196
+ rns = argv[0];
1197
+ if (TYPE(rns) == T_STRING) {
1198
+ cp = strchr(StringValuePtr(rns), (int)':');
1199
+ if (cp == NULL) {
1200
+ rprefix = rns;
1201
+ href = NULL;
1202
+ } else {
1203
+ rprefix = rb_str_new(StringValuePtr(rns), (int)((long)cp - (long)StringValuePtr(rns)));
1204
+ href = &cp[1]; /* skip the : */
1205
+ }
1206
+ } else if (rb_obj_is_kind_of(rns, cXMLNS) == Qtrue) {
1207
+ Data_Get_Struct(self, ruby_xml_ns, rxns);
1208
+ xmlSetNs(rxn->node, rxns->ns);
1209
+ return(rns);
1210
+ } else
1211
+ rb_raise(rb_eTypeError, "must pass a string or an XML::Ns object");
1212
+
1213
+ /* Fall through to next case because when argc == 1, we need to
1214
+ * manually setup the additional args unless the arg passed is of
1215
+ * cXMLNS type */
1216
+ case 2:
1217
+ /* Don't want this code run in the fall through case */
1218
+ if (argc == 2) {
1219
+ rprefix = argv[0];
1220
+ href = StringValuePtr(argv[1]);
1221
+ }
1222
+
1223
+ ns = xmlNewNs(rxn->node, (xmlChar*)href, (xmlChar*)StringValuePtr(rprefix));
1224
+ if (ns == NULL)
1225
+ rb_raise(eXMLNodeSetNamespace, "unable to set the namespace");
1226
+ else
1227
+ return ruby_xml_ns_new2(cXMLNS, ruby_xml_document_wrap(rxn->node->doc), ns);
1228
+ break;
1229
+
1230
+ default:
1231
+ rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
1232
+ }
1233
+
1234
+ /* can't get here */
1235
+ return(Qnil);
1236
+ }
1237
+
1238
+
1239
+ /*
1240
+ * call-seq:
1241
+ * node.namespace? => (true|false)
1242
+ *
1243
+ * Determine whether this node *is* (not has) a namespace
1244
+ * node.
1245
+ */
1246
+ VALUE
1247
+ ruby_xml_node_namespace_q(VALUE self) {
1248
+ ruby_xml_node *rxn;
1249
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1250
+ if (rxn->node->type == XML_NAMESPACE_DECL)
1251
+ return(Qtrue);
1252
+ else
1253
+ return(Qfalse);
1254
+ }
1255
+
1256
+ /*
1257
+ * memory2 implementation: xmlNode->_private holds a reference
1258
+ * to the wrapping ruby object VALUE when there is one.
1259
+ * traversal for marking is upward, and top levels are marked
1260
+ * through and lower level mark entry.
1261
+ *
1262
+ * All ruby retrieval for an xml
1263
+ * node will result in the same ruby instance. When all handles to them
1264
+ * go out of scope, then ruby_xfree gets called and _private is set to NULL.
1265
+ * If the xmlNode has no parent or document, then call xmlFree.
1266
+ */
1267
+ void
1268
+ ruby_xml_node2_free(ruby_xml_node *rxn) {
1269
+
1270
+ if (rxn == NULL ) return;
1271
+
1272
+ if (rxn->node != NULL ) {
1273
+ rxn->node->_private=NULL;
1274
+
1275
+ if ( rxn->node->doc==NULL || rxn->node->parent==NULL ) {
1276
+ #ifdef NODE_DEBUG
1277
+ fprintf(stderr,"ruby_xml_node2_free ruby_xfree rxn=0x%x xn=0x%x o=0x%x\n",(long)rxn,(long)rxn->node,(long)rxn->node->_private);
1278
+ #endif
1279
+ xmlFreeNode(rxn->node);
1280
+ }
1281
+
1282
+ rxn->node=NULL;
1283
+ }
1284
+
1285
+ ruby_xfree(rxn);
1286
+ }
1287
+
1288
+ void
1289
+ ruby_xml_node_mark_common(xmlNodePtr node) {
1290
+ if (node->parent == NULL ) {
1291
+ #ifdef NODE_DEBUG
1292
+ fprintf(stderr,"mark no parent r=0x%x *n=0x%x\n",rxn,node);
1293
+ #endif
1294
+ } else if ( node->doc != NULL ) {
1295
+ if (node->doc->_private == NULL) {
1296
+ rb_bug("XmlNode Doc is not bound! (%s:%d)",
1297
+ __FILE__,__LINE__);
1298
+ }
1299
+ rb_gc_mark((VALUE)node->doc->_private);
1300
+ } else {
1301
+ while (node->parent != NULL )
1302
+ node=node->parent;
1303
+ if (node->_private == NULL )
1304
+ rb_warning("XmlNode Root Parent is not bound! (%s:%d)",
1305
+ __FILE__,__LINE__);
1306
+ else {
1307
+ #ifdef NODE_DEBUG
1308
+ fprintf(stderr,"mark rxn=0x%x xn=0x%x o=0x%x doc=0x%x\n",(long)rxn,(long)node,(long)node->_private,node->doc);
1309
+ #endif
1310
+ rb_gc_mark((VALUE)node->_private);
1311
+ }
1312
+ }
1313
+ }
1314
+
1315
+ void
1316
+ ruby_xml_node2_mark(ruby_xml_node *rxn) {
1317
+ if (rxn->node == NULL ) return;
1318
+
1319
+ if (rxn->node->_private == NULL ) {
1320
+ rb_warning("XmlNode is not bound! (%s:%d)",
1321
+ __FILE__,__LINE__);
1322
+ return;
1323
+ }
1324
+
1325
+ ruby_xml_node_mark_common(rxn->node);
1326
+ }
1327
+
1328
+ VALUE
1329
+ ruby_xml_node2_wrap(VALUE class, xmlNodePtr xnode)
1330
+ {
1331
+ VALUE obj;
1332
+ ruby_xml_node *rxn;
1333
+
1334
+ // This node is already wrapped
1335
+ if (xnode->_private != NULL) {
1336
+ #ifdef NODE_DEBUG
1337
+ Data_Get_Struct((VALUE)xnode->_private,ruby_xml_node,rxn);
1338
+ fprintf(stderr,"re-wrap rn=0x%x n*=0x%x\n",(long)rxn,(long)xnode);
1339
+ #endif
1340
+ return (VALUE)xnode->_private;
1341
+ }
1342
+
1343
+ obj=Data_Make_Struct(class,ruby_xml_node,ruby_xml_node2_mark,
1344
+ ruby_xml_node2_free,rxn);
1345
+
1346
+ rxn->node=xnode;
1347
+ xnode->_private=(void*)obj;
1348
+ #ifdef NODE_DEBUG
1349
+ fprintf(stderr,"wrap rn=0x%x n*=0x%x d*=0x%x\n",
1350
+ (long)rxn,(long)xnode,xnode->doc);
1351
+ #endif
1352
+ return obj;
1353
+ }
1354
+
1355
+ VALUE
1356
+ ruby_xml_node2_new_native(VALUE class, VALUE ns, VALUE name)
1357
+ {
1358
+ VALUE obj;
1359
+ xmlNodePtr xnode;
1360
+ xmlNsPtr xns=NULL;
1361
+
1362
+ if ( ! NIL_P(ns) ) {
1363
+ Data_Get_Struct(ns,xmlNs,xns);
1364
+ }
1365
+ xnode=xmlNewNode(xns,(xmlChar*)StringValuePtr(name));
1366
+ xnode->_private=NULL;
1367
+
1368
+ obj=
1369
+ ruby_xml_node2_wrap(class,xnode);
1370
+
1371
+ rb_obj_call_init(obj,0,NULL);
1372
+ return obj;
1373
+ }
1374
+
1375
+ VALUE
1376
+ ruby_xml_node2_new_string(VALUE class, VALUE ns, VALUE name, VALUE val)
1377
+ {
1378
+ VALUE obj;
1379
+ obj=ruby_xml_node2_new_native(class,ns,name);
1380
+ if ( ! NIL_P(val) ) {
1381
+ if ( TYPE(val) != T_STRING )
1382
+ val=rb_obj_as_string(val);
1383
+ ruby_xml_node_content_set(obj,val);
1384
+ }
1385
+ return obj;
1386
+ }
1387
+ /*
1388
+ * call-seq:
1389
+ * XML::Node.new(name, content = nil) => node
1390
+ * XML::Node.new_element(name, content = nil) => node
1391
+ *
1392
+ * Create a new element node with the specified name, optionally setting
1393
+ * the node's content.
1394
+ * backward compatibility for <.5 new
1395
+ */
1396
+ VALUE
1397
+ ruby_xml_node2_new_string_bc(int argc, VALUE *argv, VALUE class)
1398
+ {
1399
+ VALUE content=Qnil;
1400
+ VALUE name=Qnil;
1401
+ switch(argc) {
1402
+ case 2:
1403
+ content=argv[1];
1404
+ if ( TYPE(content) != T_STRING)
1405
+ content=rb_obj_as_string(content);
1406
+
1407
+ case 1:
1408
+ name=check_string_or_symbol( argv[0] );
1409
+ return ruby_xml_node2_new_string(class,Qnil,name,content);
1410
+
1411
+ default:
1412
+ rb_raise(rb_eArgError, "wrong number of arguments (1 or 2) given %d",argc);
1413
+ }
1414
+ }
1415
+
1416
+ /*
1417
+ * call-seq:
1418
+ * node.next => node
1419
+ *
1420
+ * Obtain the next sibling node, if any.
1421
+ */
1422
+ VALUE
1423
+ ruby_xml_node_next_get(VALUE self) {
1424
+ ruby_xml_node *rxn;
1425
+ xmlNodePtr node;
1426
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1427
+
1428
+ switch (rxn->node->type) {
1429
+ case XML_DOCUMENT_NODE:
1430
+ #ifdef LIBXML_DOCB_ENABLED
1431
+ case XML_DOCB_DOCUMENT_NODE:
1432
+ #endif
1433
+ case XML_HTML_DOCUMENT_NODE:
1434
+ node = NULL;
1435
+ break;
1436
+ case XML_ATTRIBUTE_NODE:
1437
+ {
1438
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1439
+ node = (xmlNodePtr) attr->next;
1440
+ break;
1441
+ }
1442
+ case XML_NAMESPACE_DECL:
1443
+ {
1444
+ xmlNsPtr ns = (xmlNsPtr) rxn->node;
1445
+ node = (xmlNodePtr) ns->next;
1446
+ break;
1447
+ }
1448
+ default:
1449
+ node = rxn->node->next;
1450
+ break;
1451
+ }
1452
+
1453
+ if (node == NULL) {
1454
+ return(Qnil);
1455
+ } else {
1456
+ return(ruby_xml_node2_wrap(cXMLNode, node));
1457
+ }
1458
+ }
1459
+
1460
+
1461
+ /*
1462
+ * call-seq:
1463
+ * node.next? => (true|false)
1464
+ *
1465
+ * Determine whether this node has a next sibling.
1466
+ */
1467
+ VALUE
1468
+ ruby_xml_node_next_q(VALUE self) {
1469
+ ruby_xml_node *rxn;
1470
+ xmlNodePtr node;
1471
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1472
+
1473
+ switch (rxn->node->type) {
1474
+ case XML_DOCUMENT_NODE:
1475
+ #ifdef LIBXML_DOCB_ENABLED
1476
+ case XML_DOCB_DOCUMENT_NODE:
1477
+ #endif
1478
+ case XML_HTML_DOCUMENT_NODE:
1479
+ node = NULL;
1480
+ break;
1481
+ case XML_ATTRIBUTE_NODE:
1482
+ {
1483
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1484
+ node = (xmlNodePtr) attr->next;
1485
+ break;
1486
+ }
1487
+ case XML_NAMESPACE_DECL:
1488
+ {
1489
+ xmlNsPtr ns = (xmlNsPtr) rxn->node;
1490
+ node = (xmlNodePtr) ns->next;
1491
+ break;
1492
+ }
1493
+ default:
1494
+ node = rxn->node->next;
1495
+ break;
1496
+ }
1497
+
1498
+ if (node == NULL)
1499
+ return(Qfalse);
1500
+ else
1501
+ return(Qtrue);
1502
+ }
1503
+
1504
+
1505
+ /*
1506
+ * call-seq:
1507
+ * node.next = node
1508
+ *
1509
+ * Insert the specified node as this node's next sibling.
1510
+ */
1511
+ VALUE
1512
+ ruby_xml_node_next_set(VALUE self, VALUE rnode) {
1513
+ ruby_xml_node *cnode, *pnode;
1514
+ xmlNodePtr ret;
1515
+
1516
+ if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
1517
+ rb_raise(rb_eTypeError, "Must pass an XML::Node object");
1518
+
1519
+ Data_Get_Struct(self, ruby_xml_node, pnode);
1520
+ Data_Get_Struct(rnode, ruby_xml_node, cnode);
1521
+
1522
+ ret = xmlAddNextSibling(pnode->node, cnode->node);
1523
+ if (ret == NULL)
1524
+ rb_raise(eXMLNodeFailedModify, "unable to add a sibling to the document");
1525
+
1526
+ return(ruby_xml_node2_wrap(cXMLNode, ret));
1527
+ }
1528
+
1529
+
1530
+ /*
1531
+ * call-seq:
1532
+ * node.notation? => (true|false)
1533
+ *
1534
+ * Determine whether this is a notation node
1535
+ */
1536
+ VALUE
1537
+ ruby_xml_node_notation_q(VALUE self) {
1538
+ ruby_xml_node *rxn;
1539
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1540
+ if (rxn->node->type == XML_NOTATION_NODE)
1541
+ return(Qtrue);
1542
+ else
1543
+ return(Qfalse);
1544
+ }
1545
+
1546
+
1547
+ /*
1548
+ * call-seq:
1549
+ * node.ns? => (true|false)
1550
+ *
1551
+ * Determine whether this node is a namespace node.
1552
+ */
1553
+ VALUE
1554
+ ruby_xml_node_ns_q(VALUE self) {
1555
+ ruby_xml_node *rxn;
1556
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1557
+ if (rxn->node->ns == NULL)
1558
+ return(Qfalse);
1559
+ else
1560
+ return(Qtrue);
1561
+ }
1562
+
1563
+
1564
+ /*
1565
+ * call-seq:
1566
+ * node.ns_def => namespace
1567
+ *
1568
+ * Obtain this node's default namespace.
1569
+ */
1570
+ VALUE
1571
+ ruby_xml_node_ns_def_get(VALUE self) {
1572
+ ruby_xml_node *rxn;
1573
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1574
+ if (rxn->node->nsDef == NULL)
1575
+ return(Qnil);
1576
+ else
1577
+ return(ruby_xml_ns_new2(cXMLNS, ruby_xml_document_wrap(rxn->node->doc), rxn->node->nsDef));
1578
+ }
1579
+
1580
+
1581
+ /*
1582
+ * call-seq:
1583
+ * node.ns_def? => (true|false)
1584
+ *
1585
+ * Obtain an array of +XML::NS+ objects representing
1586
+ * this node's xmlns attributes
1587
+ */
1588
+ VALUE
1589
+ ruby_xml_node_ns_def_q(VALUE self) {
1590
+ ruby_xml_node *rxn;
1591
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1592
+ if (rxn->node->nsDef == NULL)
1593
+ return(Qfalse);
1594
+ else
1595
+ return(Qtrue);
1596
+ }
1597
+
1598
+
1599
+ /*
1600
+ * call-seq:
1601
+ * node.parent => node
1602
+ *
1603
+ * Obtain this node's parent node, if any.
1604
+ */
1605
+ VALUE
1606
+ ruby_xml_node_parent_get(VALUE self) {
1607
+ ruby_xml_node *rxn;
1608
+ xmlNodePtr node;
1609
+
1610
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1611
+
1612
+ switch (rxn->node->type) {
1613
+ case XML_DOCUMENT_NODE:
1614
+ case XML_HTML_DOCUMENT_NODE:
1615
+ #ifdef LIBXML_DOCB_ENABLED
1616
+ case XML_DOCB_DOCUMENT_NODE:
1617
+ #endif
1618
+ node = NULL;
1619
+ break;
1620
+ case XML_ATTRIBUTE_NODE:
1621
+ {
1622
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1623
+ node = attr->parent;
1624
+ }
1625
+ case XML_ENTITY_DECL:
1626
+ case XML_NAMESPACE_DECL:
1627
+ case XML_XINCLUDE_START:
1628
+ case XML_XINCLUDE_END:
1629
+ node = NULL;
1630
+ break;
1631
+ default:
1632
+ node = rxn->node->parent;
1633
+ break;
1634
+ }
1635
+
1636
+ if (node == NULL)
1637
+ return(Qnil);
1638
+ else
1639
+ return(ruby_xml_node2_wrap(cXMLNode, node));
1640
+ }
1641
+
1642
+
1643
+ /*
1644
+ * call-seq:
1645
+ * node.parent? => (true|false)
1646
+ *
1647
+ * Determine whether this node has a parent node.
1648
+ */
1649
+ VALUE
1650
+ ruby_xml_node_parent_q(VALUE self) {
1651
+ ruby_xml_node *rxn;
1652
+ xmlNodePtr node;
1653
+
1654
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1655
+
1656
+ switch (rxn->node->type) {
1657
+ case XML_DOCUMENT_NODE:
1658
+ case XML_HTML_DOCUMENT_NODE:
1659
+ #ifdef LIBXML_DOCB_ENABLED
1660
+ case XML_DOCB_DOCUMENT_NODE:
1661
+ #endif
1662
+ node = NULL;
1663
+ break;
1664
+ case XML_ATTRIBUTE_NODE:
1665
+ {
1666
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1667
+ node = attr->parent;
1668
+ }
1669
+ case XML_ENTITY_DECL:
1670
+ case XML_NAMESPACE_DECL:
1671
+ case XML_XINCLUDE_START:
1672
+ case XML_XINCLUDE_END:
1673
+ node = NULL;
1674
+ break;
1675
+ default:
1676
+ node = rxn->node->parent;
1677
+ break;
1678
+ }
1679
+
1680
+ if (node == NULL)
1681
+ return(Qfalse);
1682
+ else
1683
+ return(Qtrue);
1684
+ }
1685
+
1686
+
1687
+ /*
1688
+ * call-seq:
1689
+ * node.path => path
1690
+ *
1691
+ * Obtain this node's path.
1692
+ */
1693
+ VALUE
1694
+ ruby_xml_node_path(VALUE self) {
1695
+ ruby_xml_node *rxn;
1696
+ xmlChar *path;
1697
+
1698
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1699
+ path = xmlGetNodePath(rxn->node);
1700
+
1701
+ if (path == NULL)
1702
+ return(Qnil);
1703
+ else
1704
+ return(rb_str_new2((const char*)path));
1705
+ }
1706
+
1707
+
1708
+ /*
1709
+ * call-seq:
1710
+ * node.pi? => (true|false)
1711
+ *
1712
+ * Determine whether this is a processing instruction node.
1713
+ */
1714
+ VALUE
1715
+ ruby_xml_node_pi_q(VALUE self) {
1716
+ ruby_xml_node *rxn;
1717
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1718
+ if (rxn->node->type == XML_PI_NODE)
1719
+ return(Qtrue);
1720
+ else
1721
+ return(Qfalse);
1722
+ }
1723
+
1724
+
1725
+ /*
1726
+ * call-seq:
1727
+ * node.pointer => node_set
1728
+ *
1729
+ * Evaluates an XPointer expression relative to this node.
1730
+ */
1731
+ VALUE
1732
+ ruby_xml_node_pointer(VALUE self, VALUE xptr_str) {
1733
+ return(ruby_xml_xpointer_point2(self, xptr_str));
1734
+ }
1735
+
1736
+
1737
+ /*
1738
+ * call-seq:
1739
+ * node.prev => node
1740
+ *
1741
+ * Obtain the previous sibling, if any.
1742
+ */
1743
+ VALUE
1744
+ ruby_xml_node_prev_get(VALUE self) {
1745
+ ruby_xml_node *rxn;
1746
+ xmlNodePtr node;
1747
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1748
+
1749
+ switch (rxn->node->type) {
1750
+ case XML_DOCUMENT_NODE:
1751
+ #ifdef LIBXML_DOCB_ENABLED
1752
+ case XML_DOCB_DOCUMENT_NODE:
1753
+ #endif
1754
+ case XML_HTML_DOCUMENT_NODE:
1755
+ case XML_NAMESPACE_DECL:
1756
+ node = NULL;
1757
+ break;
1758
+ case XML_ATTRIBUTE_NODE:
1759
+ {
1760
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1761
+ node = (xmlNodePtr) attr->prev;
1762
+ }
1763
+ break;
1764
+ default:
1765
+ node = rxn->node->prev;
1766
+ break;
1767
+ }
1768
+
1769
+ if (node == NULL)
1770
+ return(Qnil);
1771
+ else
1772
+ return(ruby_xml_node2_wrap(cXMLNode, node));
1773
+ }
1774
+
1775
+
1776
+ /*
1777
+ * call-seq:
1778
+ * node.prev? => (true|false)
1779
+ *
1780
+ * Determines whether this node has a previous sibling node.
1781
+ */
1782
+ VALUE
1783
+ ruby_xml_node_prev_q(VALUE self) {
1784
+ ruby_xml_node *rxn;
1785
+ xmlNodePtr node;
1786
+
1787
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1788
+
1789
+ switch (rxn->node->type) {
1790
+ case XML_DOCUMENT_NODE:
1791
+ #ifdef LIBXML_DOCB_ENABLED
1792
+ case XML_DOCB_DOCUMENT_NODE:
1793
+ #endif
1794
+ case XML_HTML_DOCUMENT_NODE:
1795
+ case XML_NAMESPACE_DECL:
1796
+ node = NULL;
1797
+ break;
1798
+ case XML_ATTRIBUTE_NODE:
1799
+ {
1800
+ xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
1801
+ node = (xmlNodePtr) attr->prev;
1802
+ }
1803
+ break;
1804
+ default:
1805
+ node = rxn->node->prev;
1806
+ break;
1807
+ }
1808
+
1809
+ if (node == NULL)
1810
+ return(Qfalse);
1811
+ else
1812
+ return(Qtrue);
1813
+ }
1814
+
1815
+
1816
+ /*
1817
+ * call-seq:
1818
+ * node.prev = node
1819
+ *
1820
+ * Insert the specified node as this node's previous sibling.
1821
+ */
1822
+ VALUE
1823
+ ruby_xml_node_prev_set(VALUE self, VALUE rnode) {
1824
+ ruby_xml_node *cnode, *pnode;
1825
+ xmlNodePtr ret;
1826
+
1827
+ if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
1828
+ rb_raise(rb_eTypeError, "Must pass an XML::Node object");
1829
+
1830
+ Data_Get_Struct(self, ruby_xml_node, pnode);
1831
+ Data_Get_Struct(rnode, ruby_xml_node, cnode);
1832
+
1833
+ ret = xmlAddPrevSibling(pnode->node, cnode->node);
1834
+ if (ret == NULL)
1835
+ rb_raise(eXMLNodeFailedModify, "unable to add a sibling to the document");
1836
+
1837
+ return(ruby_xml_node2_wrap(cXMLNode, ret));
1838
+ }
1839
+
1840
+
1841
+ /*
1842
+ * call-seq:
1843
+ * node.property("name") => "string"
1844
+ * node["name"] => "string"
1845
+ *
1846
+ * Obtain the named property.
1847
+ */
1848
+ VALUE
1849
+ ruby_xml_node_property_get(VALUE self, VALUE prop) {
1850
+ ruby_xml_node *rxn;
1851
+ xmlChar *p;
1852
+ VALUE result = Qnil;
1853
+
1854
+ prop = check_string_or_symbol( prop );
1855
+
1856
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1857
+ p = xmlGetProp(rxn->node, (xmlChar*)StringValuePtr(prop));
1858
+
1859
+ if (p) {
1860
+ result = rb_str_new2((const char*)p);
1861
+ xmlFree(p);
1862
+ }
1863
+
1864
+ return result;
1865
+ }
1866
+
1867
+
1868
+ /*
1869
+ * call-seq:
1870
+ * node["name"] = "string"
1871
+ *
1872
+ * Set the named property.
1873
+ */
1874
+ VALUE
1875
+ ruby_xml_node_property_set(VALUE self, VALUE key, VALUE val) {
1876
+ ruby_xml_node *node;
1877
+ xmlAttrPtr attr;
1878
+
1879
+ key = check_string_or_symbol( key );
1880
+ Data_Get_Struct(self, ruby_xml_node, node);
1881
+
1882
+ if( val == Qnil ) {
1883
+ attr = xmlSetProp(node->node, (xmlChar*)StringValuePtr(key), NULL);
1884
+ if (attr->_private == NULL)
1885
+ xmlRemoveProp( attr );
1886
+ else
1887
+ xmlUnlinkNode( attr );
1888
+ return Qnil;
1889
+ } else {
1890
+ Check_Type(val, T_STRING);
1891
+ }
1892
+
1893
+ attr = xmlSetProp(node->node, (xmlChar*)StringValuePtr(key), (xmlChar*)StringValuePtr(val));
1894
+ if (attr == NULL) {
1895
+ attr = xmlNewProp(node->node, (xmlChar*)StringValuePtr(key), (xmlChar*)StringValuePtr(val));
1896
+ if (attr == NULL)
1897
+ return(Qnil);
1898
+ }
1899
+ return(ruby_xml_attr_new(cXMLAttr, attr));
1900
+ }
1901
+
1902
+
1903
+ /*
1904
+ * call-seq:
1905
+ * node.properties => attributes
1906
+ *
1907
+ * Returns the +XML::Attr+ for this node.
1908
+ */
1909
+ VALUE
1910
+ ruby_xml_node_properties_get(VALUE self) {
1911
+ ruby_xml_node *node;
1912
+ xmlAttrPtr attr;
1913
+
1914
+ Data_Get_Struct(self, ruby_xml_node, node);
1915
+
1916
+ if (node->node->type == XML_ELEMENT_NODE) {
1917
+ attr = node->node->properties;
1918
+
1919
+ if (attr == NULL) {
1920
+ return(Qnil);
1921
+ } else {
1922
+ return(ruby_xml_attr_wrap(cXMLAttr, attr));
1923
+ }
1924
+ } else {
1925
+ return(Qnil);
1926
+ }
1927
+ }
1928
+
1929
+
1930
+ /*
1931
+ * call-seq:
1932
+ * node.properties? => (true|false)
1933
+ *
1934
+ * Determine whether this node has properties
1935
+ * (attributes).
1936
+ */
1937
+ VALUE
1938
+ ruby_xml_node_properties_q(VALUE self) {
1939
+ ruby_xml_node *rxn;
1940
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1941
+ if (rxn->node->type == XML_ELEMENT_NODE && rxn->node->properties != NULL)
1942
+ return(Qtrue);
1943
+ else
1944
+ return(Qfalse);
1945
+ }
1946
+
1947
+
1948
+ /*
1949
+ * call-seq:
1950
+ * node.remove! => nil
1951
+ *
1952
+ * Removes this node from it's parent.
1953
+ */
1954
+ VALUE
1955
+ ruby_xml_node_remove_ex(VALUE self) {
1956
+ ruby_xml_node *rxn;
1957
+ Data_Get_Struct(self, ruby_xml_node, rxn);
1958
+ xmlUnlinkNode(rxn->node);
1959
+ return(Qnil);
1960
+ }
1961
+
1962
+
1963
+ /*
1964
+ * call-seq:
1965
+ * node.search_href => namespace
1966
+ *
1967
+ * Search for a namespace by href.
1968
+ */
1969
+ VALUE
1970
+ ruby_xml_node_search_href(VALUE self, VALUE href) {
1971
+ ruby_xml_node *node;
1972
+
1973
+ Check_Type(href, T_STRING);
1974
+ Data_Get_Struct(self, ruby_xml_node, node);
1975
+ return(ruby_xml_ns_new2(cXMLNS, ruby_xml_document_wrap(node->node->doc),
1976
+ xmlSearchNsByHref(node->node->doc, node->node,
1977
+ (xmlChar*)StringValuePtr(href))));
1978
+ }
1979
+
1980
+
1981
+ /*
1982
+ * call-seq:
1983
+ * node.search_ns => namespace
1984
+ *
1985
+ * Search for a namespace by namespace.
1986
+ */
1987
+ VALUE
1988
+ ruby_xml_node_search_ns(VALUE self, VALUE ns) {
1989
+ ruby_xml_node *node;
1990
+
1991
+ Check_Type(ns, T_STRING);
1992
+ Data_Get_Struct(self, ruby_xml_node, node);
1993
+ return(ruby_xml_ns_new2(cXMLNS,
1994
+ ruby_xml_document_wrap(node->node->doc),
1995
+ xmlSearchNs(node->node->doc, node->node,
1996
+ (xmlChar*)StringValuePtr(ns))));
1997
+ }
1998
+
1999
+
2000
+ /*
2001
+ * call-seq:
2002
+ * node.sibling(node) => node
2003
+ *
2004
+ * Add the specified node as a sibling of this node.
2005
+ */
2006
+ VALUE
2007
+ ruby_xml_node_sibling_set(VALUE self, VALUE rnode) {
2008
+ ruby_xml_node *cnode, *pnode;
2009
+ xmlNodePtr ret;
2010
+ VALUE obj;
2011
+
2012
+ if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
2013
+ rb_raise(rb_eTypeError, "Must pass an XML::Node object");
2014
+
2015
+ Data_Get_Struct(self, ruby_xml_node, pnode);
2016
+ Data_Get_Struct(rnode, ruby_xml_node, cnode);
2017
+
2018
+ ret = xmlAddSibling(pnode->node, cnode->node);
2019
+ if (ret == NULL)
2020
+ rb_raise(eXMLNodeFailedModify, "unable to add a sibling to the document");
2021
+ if (ret->_private==NULL)
2022
+ obj=ruby_xml_node2_wrap(cXMLNode,ret);
2023
+ else
2024
+ obj=(VALUE)ret->_private;
2025
+
2026
+ return obj;
2027
+ }
2028
+
2029
+
2030
+ /*
2031
+ * call-seq:
2032
+ * node.space_preserve => (true|false)
2033
+ *
2034
+ * Determine whether this node preserves whitespace.
2035
+ */
2036
+ VALUE
2037
+ ruby_xml_node_space_preserve_get(VALUE self) {
2038
+ ruby_xml_node *rxn;
2039
+
2040
+ Data_Get_Struct(self, ruby_xml_node, rxn);
2041
+ return(INT2NUM(xmlNodeGetSpacePreserve(rxn->node)));
2042
+ }
2043
+
2044
+
2045
+ /*
2046
+ * call-seq:
2047
+ * node.space_preserve = true|false
2048
+ *
2049
+ * Control whether this node preserves whitespace.
2050
+ */
2051
+ VALUE
2052
+ ruby_xml_node_space_preserve_set(VALUE self, VALUE bool) {
2053
+ ruby_xml_node *rxn;
2054
+ Data_Get_Struct(self, ruby_xml_node, rxn);
2055
+
2056
+ if (TYPE(bool) == T_FALSE)
2057
+ xmlNodeSetSpacePreserve(rxn->node, 1);
2058
+ else
2059
+ xmlNodeSetSpacePreserve(rxn->node, 0);
2060
+
2061
+ return(Qnil);
2062
+ }
2063
+
2064
+
2065
+ /*
2066
+ * call-seq:
2067
+ * node.text? => (true|false)
2068
+ *
2069
+ * Determine whether this node has text.
2070
+ */
2071
+ VALUE
2072
+ ruby_xml_node_text_q(VALUE self) {
2073
+ ruby_xml_node *rxn;
2074
+ Data_Get_Struct(self, ruby_xml_node, rxn);
2075
+ if (rxn->node == NULL)
2076
+ return(Qnil);
2077
+
2078
+ return((xmlNodeIsText(rxn->node) == 1) ? Qtrue : Qfalse);
2079
+ }
2080
+
2081
+
2082
+ /*
2083
+ * call-seq:
2084
+ * node.to_s => "string"
2085
+ *
2086
+ * Coerce this node to a string representation of
2087
+ * it's XML.
2088
+ */
2089
+ VALUE
2090
+ ruby_xml_node_to_s(VALUE self) {
2091
+ ruby_xml_node *rxn;
2092
+ xmlBufferPtr buf;
2093
+ VALUE result;
2094
+
2095
+ Data_Get_Struct(self, ruby_xml_node, rxn);
2096
+ buf = xmlBufferCreate();
2097
+ xmlNodeDump(buf, rxn->node->doc, rxn->node, 0, 1);
2098
+ result = rb_str_new2((const char*)buf->content);
2099
+
2100
+ xmlBufferFree(buf);
2101
+ return result;
2102
+ }
2103
+
2104
+
2105
+ /*
2106
+ * call-seq:
2107
+ * node.type => num
2108
+ *
2109
+ * Obtain this node's type identifier.
2110
+ */
2111
+ VALUE
2112
+ ruby_xml_node_type(VALUE self) {
2113
+ ruby_xml_node *rxn;
2114
+ Data_Get_Struct(self, ruby_xml_node, rxn);
2115
+ return(INT2NUM(rxn->node->type));
2116
+ }
2117
+
2118
+
2119
+ /*
2120
+ * call-seq:
2121
+ * node.type_name => num
2122
+ *
2123
+ * Obtain this node's type name.
2124
+ */
2125
+ VALUE
2126
+ ruby_xml_node_type_name(VALUE self) {
2127
+ ruby_xml_node *rxn;
2128
+ Data_Get_Struct(self, ruby_xml_node, rxn);
2129
+
2130
+ switch(rxn->node->type) {
2131
+ case XML_ELEMENT_NODE:
2132
+ return(rb_str_new2("element"));
2133
+ case XML_ATTRIBUTE_NODE:
2134
+ return(rb_str_new2("attribute"));
2135
+ case XML_TEXT_NODE:
2136
+ return(rb_str_new2("text"));
2137
+ case XML_CDATA_SECTION_NODE:
2138
+ return(rb_str_new2("cdata"));
2139
+ case XML_ENTITY_REF_NODE:
2140
+ return(rb_str_new2("entity_ref"));
2141
+ case XML_ENTITY_NODE:
2142
+ return(rb_str_new2("entity"));
2143
+ case XML_PI_NODE:
2144
+ return(rb_str_new2("pi"));
2145
+ case XML_COMMENT_NODE:
2146
+ return(rb_str_new2("comment"));
2147
+ case XML_DOCUMENT_NODE:
2148
+ return(rb_str_new2("document_xml"));
2149
+ case XML_DOCUMENT_TYPE_NODE:
2150
+ return(rb_str_new2("doctype"));
2151
+ case XML_DOCUMENT_FRAG_NODE:
2152
+ return(rb_str_new2("fragment"));
2153
+ case XML_NOTATION_NODE:
2154
+ return(rb_str_new2("notation"));
2155
+ case XML_HTML_DOCUMENT_NODE:
2156
+ return(rb_str_new2("document_html"));
2157
+ case XML_DTD_NODE:
2158
+ return(rb_str_new2("dtd"));
2159
+ case XML_ELEMENT_DECL:
2160
+ return(rb_str_new2("elem_decl"));
2161
+ case XML_ATTRIBUTE_DECL:
2162
+ return(rb_str_new2("attribute_decl"));
2163
+ case XML_ENTITY_DECL:
2164
+ return(rb_str_new2("entity_decl"));
2165
+ case XML_NAMESPACE_DECL:
2166
+ return(rb_str_new2("namespace"));
2167
+ case XML_XINCLUDE_START:
2168
+ return(rb_str_new2("xinclude_start"));
2169
+ case XML_XINCLUDE_END:
2170
+ return(rb_str_new2("xinclude_end"));
2171
+ #ifdef LIBXML_DOCB_ENABLED
2172
+ case XML_DOCB_DOCUMENT_NODE:
2173
+ return(rb_str_new2("document_docbook"));
2174
+ #endif
2175
+ default:
2176
+ rb_raise(eXMLNodeUnknownType, "Unknown node type: %n", rxn->node->type);
2177
+ return(Qfalse);
2178
+ }
2179
+ }
2180
+
2181
+
2182
+ /*
2183
+ * call-seq:
2184
+ * node.xinclude_end? => num
2185
+ *
2186
+ * Determine whether this node is an xinclude end node.
2187
+ */
2188
+ VALUE
2189
+ ruby_xml_node_xinclude_end_q(VALUE self) {
2190
+ ruby_xml_node *rxn;
2191
+ Data_Get_Struct(self, ruby_xml_node, rxn);
2192
+ if (rxn->node->type == XML_XINCLUDE_END)
2193
+ return(Qtrue);
2194
+ else
2195
+ return(Qfalse);
2196
+ }
2197
+
2198
+
2199
+ /*
2200
+ * call-seq:
2201
+ * node.xinclude_start? => num
2202
+ *
2203
+ * Determine whether this node is an xinclude start node.
2204
+ */
2205
+ VALUE
2206
+ ruby_xml_node_xinclude_start_q(VALUE self) {
2207
+ ruby_xml_node *rxn;
2208
+ Data_Get_Struct(self, ruby_xml_node, rxn);
2209
+ if (rxn->node->type == XML_XINCLUDE_START)
2210
+ return(Qtrue);
2211
+ else
2212
+ return(Qfalse);
2213
+ }
2214
+
2215
+
2216
+ /*
2217
+ * call-seq:
2218
+ * node.copy => node
2219
+ *
2220
+ * Create a copy of this node.
2221
+ */
2222
+ VALUE
2223
+ ruby_xml_node_copy(VALUE self, VALUE deep) {
2224
+ ruby_xml_node *rxn;
2225
+ xmlNode *copy;
2226
+ VALUE obj;
2227
+
2228
+ Data_Get_Struct(self, ruby_xml_node, rxn);
2229
+ copy = xmlCopyNode( rxn->node, ((deep==Qnil)||(deep==Qfalse))?0:1 );
2230
+
2231
+ if (copy == NULL)
2232
+ return Qnil;
2233
+
2234
+ obj=ruby_xml_node2_wrap(cXMLNode,copy);
2235
+ copy->_private = (void*) obj;
2236
+ return obj;
2237
+ }
2238
+
2239
+ /*
2240
+ * call-seq:
2241
+ * XML::Node.new_text(content = nil) => node
2242
+ *
2243
+ * Create a new text node, optionally setting
2244
+ * the node's content.
2245
+ *
2246
+ */
2247
+ VALUE
2248
+ ruby_xml_node_new_text(VALUE class, VALUE text)
2249
+ {
2250
+ VALUE obj;
2251
+ xmlNodePtr xnode;
2252
+
2253
+ if ( NIL_P(text) )
2254
+ return Qnil;
2255
+
2256
+ if (TYPE(text) != T_STRING )
2257
+ rb_raise(rb_eTypeError, "requires string argument");
2258
+
2259
+ xnode=xmlNewText((xmlChar*)STR2CSTR(text));
2260
+ if ( xnode == NULL )
2261
+ return Qnil;
2262
+
2263
+ obj=ruby_xml_node2_wrap(class,xnode);
2264
+ rb_obj_call_init(obj,0,NULL);
2265
+ return obj;
2266
+ }
2267
+
2268
+ void
2269
+ ruby_xml_node_registerNode(xmlNodePtr node)
2270
+ {
2271
+ node->_private=NULL;
2272
+ }
2273
+
2274
+ void
2275
+ ruby_xml_node_deregisterNode(xmlNodePtr node)
2276
+ {
2277
+ ruby_xml_node *rxn;
2278
+ if ( node->_private==NULL ) return;
2279
+ Data_Get_Struct(node->_private, ruby_xml_node, rxn);
2280
+ rxn->node=NULL;
2281
+ }
2282
+
2283
+ // Rdoc needs to know
2284
+ #ifdef RDOC_NEVER_DEFINED
2285
+ mXML = rb_define_module("XML");
2286
+ #endif
2287
+
2288
+ void
2289
+ ruby_init_xml_node(void) {
2290
+ VALUE singleton;
2291
+
2292
+ xmlRegisterNodeDefault(ruby_xml_node_registerNode);
2293
+ xmlDeregisterNodeDefault(ruby_xml_node_deregisterNode);
2294
+
2295
+ cXMLNode = rb_define_class_under(mXML, "Node", rb_cObject);
2296
+ eXMLNodeSetNamespace = rb_define_class_under(cXMLNode, "SetNamespace", eXMLError);
2297
+ eXMLNodeFailedModify = rb_define_class_under(cXMLNode, "FailedModify", eXMLError);
2298
+ eXMLNodeUnknownType = rb_define_class_under(cXMLNode, "UnknownType", eXMLError);
2299
+
2300
+ singleton = rb_singleton_class(cXMLNode);
2301
+
2302
+ rb_define_const(cXMLNode, "SPACE_DEFAULT", INT2NUM(0));
2303
+ rb_define_const(cXMLNode, "SPACE_PRESERVE", INT2NUM(1));
2304
+ rb_define_const(cXMLNode, "SPACE_NOT_INHERIT", INT2NUM(-1));
2305
+ rb_define_const(cXMLNode, "XLINK_ACTUATE_AUTO", INT2NUM(1));
2306
+ rb_define_const(cXMLNode, "XLINK_ACTUATE_NONE", INT2NUM(0));
2307
+ rb_define_const(cXMLNode, "XLINK_ACTUATE_ONREQUEST", INT2NUM(2));
2308
+ rb_define_const(cXMLNode, "XLINK_SHOW_EMBED", INT2NUM(2));
2309
+ rb_define_const(cXMLNode, "XLINK_SHOW_NEW", INT2NUM(1));
2310
+ rb_define_const(cXMLNode, "XLINK_SHOW_NONE", INT2NUM(0));
2311
+ rb_define_const(cXMLNode, "XLINK_SHOW_REPLACE", INT2NUM(3));
2312
+ rb_define_const(cXMLNode, "XLINK_TYPE_EXTENDED", INT2NUM(2));
2313
+ rb_define_const(cXMLNode, "XLINK_TYPE_EXTENDED_SET", INT2NUM(3));
2314
+ rb_define_const(cXMLNode, "XLINK_TYPE_NONE", INT2NUM(0));
2315
+ rb_define_const(cXMLNode, "XLINK_TYPE_SIMPLE", INT2NUM(1));
2316
+
2317
+ rb_define_singleton_method(cXMLNode, "new2", ruby_xml_node2_new_native, 2);
2318
+ rb_define_singleton_method(cXMLNode, "new", ruby_xml_node2_new_string_bc, -1);
2319
+ rb_define_singleton_method(cXMLNode, "new_cdata", ruby_xml_node_new_cdata, -1);
2320
+ rb_define_singleton_method(cXMLNode, "new_comment", ruby_xml_node_new_comment, -1);
2321
+ rb_define_singleton_method(cXMLNode, "new_text", ruby_xml_node_new_text, 1);
2322
+
2323
+ rb_define_alias(singleton, "new_element", "new");
2324
+
2325
+ rb_define_method(cXMLNode, "<<", ruby_xml_node_content_add, 1);
2326
+ rb_define_method(cXMLNode, "[]", ruby_xml_node_property_get, 1);
2327
+ rb_define_method(cXMLNode, "[]=", ruby_xml_node_property_set, 2);
2328
+ rb_define_method(cXMLNode, "attribute?", ruby_xml_node_attribute_q, 0);
2329
+ rb_define_method(cXMLNode, "attribute_decl?", ruby_xml_node_attribute_decl_q, 0);
2330
+ rb_define_method(cXMLNode, "base", ruby_xml_node_base_get, 0);
2331
+ rb_define_method(cXMLNode, "base=", ruby_xml_node_base_set, 1);
2332
+ rb_define_method(cXMLNode, "blank?", ruby_xml_node_empty_q, 0);
2333
+ rb_define_method(cXMLNode, "cdata?", ruby_xml_node_cdata_q, 0);
2334
+ rb_define_method(cXMLNode, "comment?", ruby_xml_node_comment_q, 0);
2335
+ rb_define_method(cXMLNode, "copy", ruby_xml_node_copy, 1);
2336
+ rb_define_method(cXMLNode, "child", ruby_xml_node_child_get, 0);
2337
+ rb_define_method(cXMLNode, "child?", ruby_xml_node_child_q, 0);
2338
+ rb_define_method(cXMLNode, "child=", ruby_xml_node_child_set, 1);
2339
+ rb_define_method(cXMLNode, "child_add", ruby_xml_node_child_add, 1);
2340
+ rb_define_method(cXMLNode, "children", ruby_xml_node_child_get, 0);
2341
+ rb_define_method(cXMLNode, "children?", ruby_xml_node_child_q, 0);
2342
+ rb_define_method(cXMLNode, "content", ruby_xml_node_content_get, 0);
2343
+ rb_define_method(cXMLNode, "content=", ruby_xml_node_content_set, 1);
2344
+ rb_define_method(cXMLNode, "content_stripped", ruby_xml_node_content_stripped_get, 0);
2345
+ rb_define_method(cXMLNode, "doc", ruby_xml_node_doc, 0);
2346
+ rb_define_method(cXMLNode, "docbook_doc?", ruby_xml_node_docbook_doc_q, 0);
2347
+ rb_define_method(cXMLNode, "doctype?", ruby_xml_node_doctype_q, 0);
2348
+ rb_define_method(cXMLNode, "document?", ruby_xml_node_document_q, 0);
2349
+ rb_define_method(cXMLNode, "dtd?", ruby_xml_node_dtd_q, 0);
2350
+ rb_define_method(cXMLNode, "dump", ruby_xml_node_dump, 0);
2351
+ rb_define_method(cXMLNode, "debug_dump", ruby_xml_node_debug_dump, 0);
2352
+ rb_define_method(cXMLNode, "element?", ruby_xml_node_element_q, 0);
2353
+ rb_define_method(cXMLNode, "element_decl?", ruby_xml_node_element_decl_q, 0);
2354
+ rb_define_method(cXMLNode, "empty?", ruby_xml_node_empty_q, 0);
2355
+ rb_define_method(cXMLNode, "entity?", ruby_xml_node_entity_q, 0);
2356
+ rb_define_method(cXMLNode, "entity_ref?", ruby_xml_node_entity_ref_q, 0);
2357
+ rb_define_method(cXMLNode, "eql?", ruby_xml_node_eql_q, 1);
2358
+ rb_define_method(cXMLNode, "find", ruby_xml_node_find, -1);
2359
+ rb_define_method(cXMLNode, "find_first", ruby_xml_node_find_first, -1);
2360
+ rb_define_method(cXMLNode, "fragment?", ruby_xml_node_fragment_q, 0);
2361
+ rb_define_method(cXMLNode, "hash", ruby_xml_node_hash, 0);
2362
+ rb_define_method(cXMLNode, "html_doc?", ruby_xml_node_html_doc_q, 0);
2363
+ rb_define_method(cXMLNode, "lang", ruby_xml_node_lang_get, 0);
2364
+ rb_define_method(cXMLNode, "lang=", ruby_xml_node_lang_set, 1);
2365
+ rb_define_method(cXMLNode, "last", ruby_xml_node_last_get, 0);
2366
+ rb_define_method(cXMLNode, "last?", ruby_xml_node_last_q, 0);
2367
+ rb_define_method(cXMLNode, "line_num", ruby_xml_node_line_num, 0);
2368
+ rb_define_method(cXMLNode, "name", ruby_xml_node_name_get, 0);
2369
+ rb_define_method(cXMLNode, "name=", ruby_xml_node_name_set, 1);
2370
+ rb_define_method(cXMLNode, "namespace", ruby_xml_node_namespace_get, 0);
2371
+ rb_define_method(cXMLNode, "namespace_node", ruby_xml_node_namespace_get_node, 0);
2372
+ rb_define_method(cXMLNode, "namespace?", ruby_xml_node_namespace_q, 0);
2373
+ rb_define_method(cXMLNode, "namespace=", ruby_xml_node_namespace_set, -1);
2374
+ rb_define_method(cXMLNode, "next", ruby_xml_node_next_get, 0);
2375
+ rb_define_method(cXMLNode, "next?", ruby_xml_node_next_q, 0);
2376
+ rb_define_method(cXMLNode, "next=", ruby_xml_node_next_set, 1);
2377
+ rb_define_method(cXMLNode, "node_type", ruby_xml_node_type, 0);
2378
+ rb_define_method(cXMLNode, "node_type_name", ruby_xml_node_type_name, 0);
2379
+ rb_define_method(cXMLNode, "notation?", ruby_xml_node_notation_q, 0);
2380
+ rb_define_method(cXMLNode, "ns", ruby_xml_node_namespace_get, 0);
2381
+ rb_define_method(cXMLNode, "ns?", ruby_xml_node_ns_q, 0);
2382
+ rb_define_method(cXMLNode, "ns_def", ruby_xml_node_ns_def_get, 0);
2383
+ rb_define_method(cXMLNode, "ns_def?", ruby_xml_node_ns_def_q, 0);
2384
+ rb_define_method(cXMLNode, "parent", ruby_xml_node_parent_get, 0);
2385
+ rb_define_method(cXMLNode, "parent?", ruby_xml_node_parent_q, 0);
2386
+ rb_define_method(cXMLNode, "path", ruby_xml_node_path, 0);
2387
+ rb_define_method(cXMLNode, "pi?", ruby_xml_node_pi_q, 0);
2388
+ rb_define_method(cXMLNode, "pointer", ruby_xml_node_pointer, 1);
2389
+ rb_define_method(cXMLNode, "prev", ruby_xml_node_prev_get, 0);
2390
+ rb_define_method(cXMLNode, "prev?", ruby_xml_node_prev_q, 0);
2391
+ rb_define_method(cXMLNode, "prev=", ruby_xml_node_prev_set, 1);
2392
+ rb_define_method(cXMLNode, "property", ruby_xml_node_property_get, 1);
2393
+ rb_define_method(cXMLNode, "properties", ruby_xml_node_properties_get, 0);
2394
+ rb_define_method(cXMLNode, "properties?", ruby_xml_node_properties_q, 0);
2395
+ rb_define_method(cXMLNode, "remove!", ruby_xml_node_remove_ex, 0);
2396
+ rb_define_method(cXMLNode, "search_ns", ruby_xml_node_search_ns, 1);
2397
+ rb_define_method(cXMLNode, "search_href", ruby_xml_node_search_href, 1);
2398
+ rb_define_method(cXMLNode, "sibling=", ruby_xml_node_sibling_set, 1);
2399
+ rb_define_method(cXMLNode, "space_preserve", ruby_xml_node_space_preserve_get, 0);
2400
+ rb_define_method(cXMLNode, "space_preserve=", ruby_xml_node_space_preserve_set, 1);
2401
+ rb_define_method(cXMLNode, "text?", ruby_xml_node_text_q, 0);
2402
+ rb_define_method(cXMLNode, "to_s", ruby_xml_node_to_s, 0);
2403
+ rb_define_method(cXMLNode, "xinclude_end?", ruby_xml_node_xinclude_end_q, 0);
2404
+ rb_define_method(cXMLNode, "xinclude_start?", ruby_xml_node_xinclude_start_q, 0);
2405
+ rb_define_method(cXMLNode, "xlink?", ruby_xml_node_xlink_q, 0);
2406
+ rb_define_method(cXMLNode, "xlink_type", ruby_xml_node_xlink_type, 0);
2407
+ rb_define_method(cXMLNode, "xlink_type_name", ruby_xml_node_xlink_type_name, 0);
2408
+
2409
+ rb_define_alias(cXMLNode, "==", "eql?");
2410
+ }