libxml-ruby 0.5.4 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }