libxml-ruby 0.8.3-x86-mswin32-60 → 0.9.0-x86-mswin32-60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. data/CHANGES +18 -0
  2. data/RAKEFILE +15 -39
  3. data/README +48 -47
  4. data/ext/libxml/libxml.c +847 -22
  5. data/ext/libxml/ruby_libxml.h +71 -95
  6. data/ext/libxml/ruby_xml_attr.c +500 -500
  7. data/ext/libxml/ruby_xml_attributes.c +1 -1
  8. data/ext/libxml/ruby_xml_document.c +1144 -1135
  9. data/ext/libxml/ruby_xml_document.h +4 -11
  10. data/ext/libxml/ruby_xml_dtd.c +27 -0
  11. data/ext/libxml/ruby_xml_encoding.c +164 -0
  12. data/ext/libxml/ruby_xml_encoding.h +13 -0
  13. data/ext/libxml/ruby_xml_error.c +941 -0
  14. data/ext/libxml/ruby_xml_error.h +13 -0
  15. data/ext/libxml/ruby_xml_html_parser.c +71 -387
  16. data/ext/libxml/ruby_xml_html_parser.h +1 -17
  17. data/ext/libxml/ruby_xml_input.c +179 -0
  18. data/ext/libxml/ruby_xml_input.h +18 -0
  19. data/ext/libxml/ruby_xml_input_cbg.c +17 -3
  20. data/ext/libxml/ruby_xml_node.c +1566 -1582
  21. data/ext/libxml/ruby_xml_node.h +1 -4
  22. data/ext/libxml/ruby_xml_ns.c +14 -3
  23. data/ext/libxml/ruby_xml_parser.c +164 -1398
  24. data/ext/libxml/ruby_xml_parser.h +5 -17
  25. data/ext/libxml/ruby_xml_parser_context.c +131 -169
  26. data/ext/libxml/ruby_xml_parser_context.h +2 -9
  27. data/ext/libxml/ruby_xml_reader.c +910 -945
  28. data/ext/libxml/ruby_xml_relaxng.c +32 -3
  29. data/ext/libxml/ruby_xml_sax_parser.c +106 -364
  30. data/ext/libxml/ruby_xml_sax_parser.h +1 -37
  31. data/ext/libxml/ruby_xml_schema.c +174 -145
  32. data/ext/libxml/ruby_xml_xinclude.c +9 -5
  33. data/ext/libxml/ruby_xml_xpath.c +25 -6
  34. data/ext/libxml/ruby_xml_xpath.h +1 -2
  35. data/ext/libxml/ruby_xml_xpath_context.c +17 -19
  36. data/ext/libxml/ruby_xml_xpath_object.c +60 -56
  37. data/ext/libxml/ruby_xml_xpointer.c +11 -5
  38. data/ext/libxml/sax_parser_callbacks.inc +42 -37
  39. data/ext/libxml/version.h +3 -3
  40. data/ext/mingw/Rakefile +20 -27
  41. data/ext/mingw/build.rake +41 -0
  42. data/{lib → ext/mingw}/libiconv-2.dll +0 -0
  43. data/ext/mingw/libxml2-2.dll +0 -0
  44. data/ext/mingw/libxml_ruby.dll.a +0 -0
  45. data/ext/mingw/libxml_ruby.so +0 -0
  46. data/ext/vc/libxml_ruby.vcproj +23 -15
  47. data/lib/libxml.rb +8 -2
  48. data/lib/libxml/document.rb +16 -4
  49. data/lib/libxml/error.rb +84 -0
  50. data/lib/libxml/hpricot.rb +76 -0
  51. data/lib/libxml/html_parser.rb +61 -0
  52. data/lib/libxml/node.rb +36 -25
  53. data/lib/libxml/parser.rb +312 -33
  54. data/lib/libxml/parser_context.rb +17 -0
  55. data/lib/libxml/properties.rb +15 -2
  56. data/lib/libxml/reader.rb +15 -0
  57. data/lib/libxml/sax_callbacks.rb +179 -0
  58. data/lib/libxml/sax_parser.rb +42 -0
  59. data/lib/libxml/tree.rb +1 -2
  60. data/lib/libxml/xpath_object.rb +12 -0
  61. data/test/model/atom.xml +4 -0
  62. data/test/tc_attributes.rb +43 -19
  63. data/test/tc_document.rb +1 -1
  64. data/test/tc_document_write.rb +15 -8
  65. data/test/tc_dtd.rb +36 -20
  66. data/test/tc_encoding.rb +13 -0
  67. data/test/tc_error.rb +136 -0
  68. data/test/tc_node.rb +2 -3
  69. data/test/tc_node_copy.rb +1 -1
  70. data/test/tc_node_edit.rb +6 -0
  71. data/test/tc_ns.rb +18 -0
  72. data/test/tc_parser.rb +113 -228
  73. data/test/tc_parser_context.rb +1 -2
  74. data/test/tc_reader.rb +24 -14
  75. data/test/tc_relaxng.rb +18 -6
  76. data/test/tc_sax_parser.rb +48 -13
  77. data/test/tc_schema.rb +20 -8
  78. data/test/tc_well_formed.rb +2 -1
  79. data/test/tc_xml.rb +212 -0
  80. data/test/tc_xpath.rb +60 -46
  81. data/test/tc_xpointer.rb +7 -11
  82. data/test/test_suite.rb +4 -3
  83. metadata +32 -115
  84. data/doc/rdoc/classes/LibXML.html +0 -241
  85. data/doc/rdoc/classes/LibXML/XML.html +0 -185
  86. data/doc/rdoc/classes/LibXML/XML/Attr.html +0 -1010
  87. data/doc/rdoc/classes/LibXML/XML/Attributes.html +0 -526
  88. data/doc/rdoc/classes/LibXML/XML/Document.html +0 -1489
  89. data/doc/rdoc/classes/LibXML/XML/Dtd.html +0 -213
  90. data/doc/rdoc/classes/LibXML/XML/Error.html +0 -117
  91. data/doc/rdoc/classes/LibXML/XML/HTMLParser.html +0 -348
  92. data/doc/rdoc/classes/LibXML/XML/InputCallbacks.html +0 -160
  93. data/doc/rdoc/classes/LibXML/XML/NS.html +0 -381
  94. data/doc/rdoc/classes/LibXML/XML/Node.html +0 -3396
  95. data/doc/rdoc/classes/LibXML/XML/Node/FailedModify.html +0 -123
  96. data/doc/rdoc/classes/LibXML/XML/Node/Set.html +0 -440
  97. data/doc/rdoc/classes/LibXML/XML/Node/SetNamespace.html +0 -123
  98. data/doc/rdoc/classes/LibXML/XML/Node/UnknownType.html +0 -123
  99. data/doc/rdoc/classes/LibXML/XML/Parser.html +0 -2239
  100. data/doc/rdoc/classes/LibXML/XML/Parser/Context.html +0 -1255
  101. data/doc/rdoc/classes/LibXML/XML/Parser/ParseError.html +0 -123
  102. data/doc/rdoc/classes/LibXML/XML/Reader.html +0 -2264
  103. data/doc/rdoc/classes/LibXML/XML/RelaxNG.html +0 -237
  104. data/doc/rdoc/classes/LibXML/XML/SaxParser.html +0 -415
  105. data/doc/rdoc/classes/LibXML/XML/Schema.html +0 -308
  106. data/doc/rdoc/classes/LibXML/XML/State.html +0 -124
  107. data/doc/rdoc/classes/LibXML/XML/Tree.html +0 -111
  108. data/doc/rdoc/classes/LibXML/XML/XInclude.html +0 -123
  109. data/doc/rdoc/classes/LibXML/XML/XInclude/Error.html +0 -117
  110. data/doc/rdoc/classes/LibXML/XML/XMLParserOptions.html +0 -198
  111. data/doc/rdoc/classes/LibXML/XML/XPath.html +0 -184
  112. data/doc/rdoc/classes/LibXML/XML/XPath/Context.html +0 -404
  113. data/doc/rdoc/classes/LibXML/XML/XPath/InvalidPath.html +0 -172
  114. data/doc/rdoc/classes/LibXML/XML/XPath/Object.html +0 -627
  115. data/doc/rdoc/classes/LibXML/XML/XPointer.html +0 -170
  116. data/doc/rdoc/classes/LibXML/XML/XPointer/Context.html +0 -123
  117. data/doc/rdoc/classes/LibXML/XML/XPointer/Context/InvalidPath.html +0 -117
  118. data/doc/rdoc/classes/LibXML/XML/XPointer/InvalidExpression.html +0 -124
  119. data/doc/rdoc/classes/singleton.html +0 -114
  120. data/doc/rdoc/created.rid +0 -1
  121. data/doc/rdoc/files/CHANGES.html +0 -442
  122. data/doc/rdoc/files/LICENSE.html +0 -133
  123. data/doc/rdoc/files/README.html +0 -388
  124. data/doc/rdoc/files/VERSION.html +0 -107
  125. data/doc/rdoc/files/ext/libxml/cbg_c.html +0 -101
  126. data/doc/rdoc/files/ext/libxml/libxml_c.html +0 -101
  127. data/doc/rdoc/files/ext/libxml/ruby_xml_attr_c.html +0 -101
  128. data/doc/rdoc/files/ext/libxml/ruby_xml_attributes_c.html +0 -101
  129. data/doc/rdoc/files/ext/libxml/ruby_xml_document_c.html +0 -101
  130. data/doc/rdoc/files/ext/libxml/ruby_xml_dtd_c.html +0 -101
  131. data/doc/rdoc/files/ext/libxml/ruby_xml_html_parser_c.html +0 -101
  132. data/doc/rdoc/files/ext/libxml/ruby_xml_input_cbg_c.html +0 -101
  133. data/doc/rdoc/files/ext/libxml/ruby_xml_node_c.html +0 -101
  134. data/doc/rdoc/files/ext/libxml/ruby_xml_node_set_c.html +0 -101
  135. data/doc/rdoc/files/ext/libxml/ruby_xml_ns_c.html +0 -101
  136. data/doc/rdoc/files/ext/libxml/ruby_xml_parser_c.html +0 -101
  137. data/doc/rdoc/files/ext/libxml/ruby_xml_parser_context_c.html +0 -101
  138. data/doc/rdoc/files/ext/libxml/ruby_xml_reader_c.html +0 -101
  139. data/doc/rdoc/files/ext/libxml/ruby_xml_relaxng_c.html +0 -101
  140. data/doc/rdoc/files/ext/libxml/ruby_xml_sax_parser_c.html +0 -101
  141. data/doc/rdoc/files/ext/libxml/ruby_xml_schema_c.html +0 -101
  142. data/doc/rdoc/files/ext/libxml/ruby_xml_state_c.html +0 -101
  143. data/doc/rdoc/files/ext/libxml/ruby_xml_xinclude_c.html +0 -101
  144. data/doc/rdoc/files/ext/libxml/ruby_xml_xpath_c.html +0 -101
  145. data/doc/rdoc/files/ext/libxml/ruby_xml_xpath_context_c.html +0 -101
  146. data/doc/rdoc/files/ext/libxml/ruby_xml_xpath_object_c.html +0 -101
  147. data/doc/rdoc/files/ext/libxml/ruby_xml_xpointer_c.html +0 -101
  148. data/doc/rdoc/files/ext/libxml/ruby_xml_xpointer_context_c.html +0 -101
  149. data/doc/rdoc/files/lib/libxml/attr_rb.html +0 -108
  150. data/doc/rdoc/files/lib/libxml/attributes_rb.html +0 -108
  151. data/doc/rdoc/files/lib/libxml/document_rb.html +0 -108
  152. data/doc/rdoc/files/lib/libxml/node_rb.html +0 -108
  153. data/doc/rdoc/files/lib/libxml/node_set_rb.html +0 -108
  154. data/doc/rdoc/files/lib/libxml/parser_options_rb.html +0 -107
  155. data/doc/rdoc/files/lib/libxml/parser_rb.html +0 -101
  156. data/doc/rdoc/files/lib/libxml/properties_rb.html +0 -108
  157. data/doc/rdoc/files/lib/libxml/tree_rb.html +0 -107
  158. data/doc/rdoc/files/lib/libxml_rb.html +0 -124
  159. data/doc/rdoc/files/lib/xml/libxml_rb.html +0 -124
  160. data/doc/rdoc/files/lib/xml_rb.html +0 -134
  161. data/doc/rdoc/fr_class_index.html +0 -62
  162. data/doc/rdoc/fr_file_index.html +0 -66
  163. data/doc/rdoc/fr_method_index.html +0 -392
  164. data/doc/rdoc/index.html +0 -24
  165. data/doc/rdoc/rdoc-style.css +0 -208
  166. data/ext/libxml/ruby_xml_node_set.c +0 -172
  167. data/ext/libxml/ruby_xml_node_set.h +0 -20
  168. data/ext/libxml/ruby_xml_xpointer_context.c +0 -22
  169. data/ext/libxml/ruby_xml_xpointer_context.h +0 -18
  170. data/lib/libxml/node_set.rb +0 -27
  171. data/lib/libxml2-2.dll +0 -0
  172. data/lib/libxml_ruby.dll.a +0 -0
  173. data/lib/libxml_ruby.so +0 -0
  174. data/test/tc_node_set.rb +0 -24
  175. data/test/tc_node_set2.rb +0 -37
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_html_parser.h 111 2006-11-20 01:39:14Z roscopeco $ */
1
+ /* $Id: ruby_xml_html_parser.h 545 2008-11-17 05:29:39Z cfis $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -8,22 +8,6 @@
8
8
  extern int ruby_xml_html_parser_count;
9
9
  extern VALUE cXMLHTMLParser;
10
10
 
11
- typedef struct ruby_xml_html_parser {
12
- VALUE ctxt;
13
- int parsed;
14
- void *data;
15
- int data_type;
16
- } ruby_xml_html_parser;
17
-
18
- /*
19
- * VALUE ruby_xml_html_parser_filename_get(VALUE self);
20
- VALUE ruby_xml_html_parser_filename_set(VALUE self, VALUE filename);
21
- VALUE ruby_xml_html_parser_new(VALUE class);
22
- */
23
- VALUE ruby_xml_html_parser_parse(VALUE self);
24
- VALUE ruby_xml_html_parser_str_get(VALUE self);
25
- VALUE ruby_xml_html_parser_str_set(VALUE self, VALUE str);
26
-
27
11
  void ruby_init_html_parser(void);
28
12
 
29
13
  #endif
@@ -0,0 +1,179 @@
1
+ /* $Id: ruby_xml_input.c 528 2008-11-15 23:43:48Z cfis $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ #include <stdarg.h>
6
+ #include "ruby_libxml.h"
7
+
8
+ VALUE cXMLInput;
9
+
10
+ /*
11
+ * Document-class: LibXML::XML::Input
12
+ *
13
+ * Input is a helper class that defines a libxml data source.
14
+ * Libxml can parse files, strings, io streams and documents
15
+ * accessible via networking protocols such as http.
16
+ * Be default, the ruby-libxml bindings expose parsing
17
+ * files, io streams and strings.
18
+ *
19
+ * Generally you will not directly work with the input object,
20
+ * but instead will use the various Document and Parser apis.
21
+ * For example:
22
+ *
23
+ * document = Document.file('my_file') */
24
+
25
+ ID ENCODING_ATTR;
26
+ ID FILE_ATTR;
27
+ ID STRING_ATTR;
28
+ ID DOCUMENT_ATTR;
29
+ ID IO_ATTR;
30
+
31
+ /*
32
+ * call-seq:
33
+ * initialize -> LibXML::XML::Input instance
34
+ *
35
+ * Initialize a new intput object.
36
+ */
37
+ VALUE
38
+ ruby_xml_input_initialize(VALUE self) {
39
+ rb_ivar_set(self, ENCODING_ATTR, INT2NUM(XML_CHAR_ENCODING_UTF8));
40
+ return self;
41
+ }
42
+
43
+
44
+ /*
45
+ * call-seq:
46
+ * input.FILE -> "FILE"
47
+ *
48
+ * Obtain the FILE this parser will read from.
49
+ */
50
+ VALUE
51
+ ruby_xml_input_file_get(VALUE self) {
52
+ return rb_ivar_get(self, FILE_ATTR);
53
+ }
54
+
55
+ /*
56
+ * call-seq:
57
+ * input.FILE = "FILE"
58
+ *
59
+ * Set the FILE this parser will read from.
60
+ */
61
+ VALUE
62
+ ruby_xml_input_file_set(VALUE self, VALUE FILE) {
63
+ Check_Type(FILE, T_STRING);
64
+ rb_ivar_set(self, FILE_ATTR, FILE);
65
+ rb_ivar_set(self, STRING_ATTR, Qnil);
66
+ rb_ivar_set(self, DOCUMENT_ATTR, Qnil);
67
+ rb_ivar_set(self, IO_ATTR, Qnil);
68
+ return self;
69
+ }
70
+
71
+
72
+ /*
73
+ * call-seq:
74
+ * input.string -> "string"
75
+ *
76
+ * Obtain the string this parser will read from.
77
+ */
78
+ VALUE
79
+ ruby_xml_input_string_get(VALUE self) {
80
+ return rb_ivar_get(self, STRING_ATTR);
81
+ }
82
+
83
+
84
+ /*
85
+ * call-seq:
86
+ * input.string = "string"
87
+ *
88
+ * Set the string this parser will read from.
89
+ */
90
+ VALUE
91
+ ruby_xml_input_string_set(VALUE self, VALUE string) {
92
+ Check_Type(string, T_STRING);
93
+ rb_ivar_set(self, FILE_ATTR, Qnil);
94
+ rb_ivar_set(self, STRING_ATTR, string);
95
+ rb_ivar_set(self, DOCUMENT_ATTR, Qnil);
96
+ rb_ivar_set(self, IO_ATTR, Qnil);
97
+ return self;
98
+ }
99
+
100
+ /*
101
+ * call-seq:
102
+ * input.document -> "document"
103
+ *
104
+ * Obtain the document this parser will read from.
105
+ */
106
+ VALUE
107
+ ruby_xml_input_document_get(VALUE self) {
108
+ return rb_ivar_get(self, DOCUMENT_ATTR);
109
+ }
110
+
111
+ /*
112
+ * call-seq:
113
+ * input.document = LibXML::XML::Document.new
114
+ *
115
+ * Set the document this parser will read from.
116
+ */
117
+ VALUE
118
+ ruby_xml_input_document_set(VALUE self, VALUE document) {
119
+ rb_ivar_set(self, FILE_ATTR, Qnil);
120
+ rb_ivar_set(self, STRING_ATTR, Qnil);
121
+ rb_ivar_set(self, DOCUMENT_ATTR, document);
122
+ rb_ivar_set(self, IO_ATTR, Qnil);
123
+ return self;
124
+ }
125
+
126
+ /*
127
+ * call-seq:
128
+ * input.io -> IO
129
+ *
130
+ * Obtain the IO instance this parser works with.
131
+ */
132
+ VALUE
133
+ ruby_xml_input_io_get(VALUE self) {
134
+ return rb_ivar_get(self, IO_ATTR);
135
+ }
136
+
137
+ /*
138
+ * call-seq:
139
+ * input.io = IO
140
+ *
141
+ * Set the IO instance this parser works with.
142
+ */
143
+ VALUE
144
+ ruby_xml_input_io_set(VALUE self, VALUE io) {
145
+ if (!rb_obj_is_kind_of(io, rb_cIO))
146
+ rb_raise(rb_eTypeError, "Invalid argument, must be an IO object");
147
+
148
+ rb_ivar_set(self, FILE_ATTR, Qnil);
149
+ rb_ivar_set(self, STRING_ATTR, Qnil);
150
+ rb_ivar_set(self, DOCUMENT_ATTR, Qnil);
151
+ rb_ivar_set(self, IO_ATTR, io);
152
+ return self;
153
+ }
154
+
155
+ // Rdoc needs to know
156
+ #ifdef RDOC_NEVER_DEFINED
157
+ mLibXML = rb_define_module("LibXML");
158
+ mXML = rb_define_module_under(mLibXML, "XML");
159
+ #endif
160
+
161
+ void
162
+ ruby_init_xml_input(void) {
163
+ FILE_ATTR = rb_intern("@FILE");
164
+ STRING_ATTR = rb_intern("@string");
165
+ DOCUMENT_ATTR = rb_intern("@document");
166
+ IO_ATTR = rb_intern("@io");
167
+
168
+ cXMLInput = rb_define_class_under(mXML, "Input", rb_cObject);
169
+ rb_define_attr(cXMLInput, "encoding", 1, 1);
170
+ rb_define_method(cXMLInput, "initialize", ruby_xml_input_initialize, 0);
171
+ rb_define_method(cXMLInput, "file", ruby_xml_input_file_get, 0);
172
+ rb_define_method(cXMLInput, "file=", ruby_xml_input_file_set, 1);
173
+ rb_define_method(cXMLInput, "string", ruby_xml_input_string_get, 0);
174
+ rb_define_method(cXMLInput, "string=", ruby_xml_input_string_set, 1);
175
+ rb_define_method(cXMLInput, "document", ruby_xml_input_document_get, 0);
176
+ rb_define_method(cXMLInput, "document=", ruby_xml_input_document_set, 1);
177
+ rb_define_method(cXMLInput, "io", ruby_xml_input_io_get, 0);
178
+ rb_define_method(cXMLInput, "io=", ruby_xml_input_io_set, 1);
179
+ }
@@ -0,0 +1,18 @@
1
+ /* $Id: ruby_xml_parser.h 39 2006-02-21 20:40:16Z roscopeco $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ #ifndef __RUBY_XML_INPUT__
6
+ #define __RUBY_XML_INPUT__
7
+
8
+ extern VALUE cXMLInput;
9
+
10
+ void ruby_init_xml_input();
11
+
12
+ extern ID ENCODING_ATTR;
13
+ extern ID FILE_ATTR;
14
+ extern ID STRING_ATTR;
15
+ extern ID DOCUMENT_ATTR;
16
+ extern ID IO_ATTR;
17
+
18
+ #endif
@@ -1,10 +1,12 @@
1
-
2
- /* ruby support for custom scheme handlers */
3
1
  /* Author: Martin Povolny (xpovolny@fi.muni.cz) */
4
2
 
5
3
  #include "ruby_libxml.h"
6
4
  #include "ruby_xml_input_cbg.h"
7
5
 
6
+ /* Document-class: LibXML::XML::InputCallbacks
7
+ *
8
+ * Support for adding custom scheme handlers. */
9
+
8
10
  static ic_scheme *first_scheme = 0;
9
11
 
10
12
  int ic_match (char const *filename) {
@@ -82,6 +84,13 @@ VALUE input_callbacks_register_input_callbacks() {
82
84
  return(Qtrue);
83
85
  }
84
86
 
87
+
88
+ /*
89
+ * call-seq:
90
+ * add_scheme
91
+ *
92
+ * No documentation available.
93
+ */
85
94
  VALUE
86
95
  input_callbacks_add_scheme (VALUE self, VALUE scheme_name, VALUE class) {
87
96
  ic_scheme *scheme;
@@ -109,6 +118,12 @@ input_callbacks_add_scheme (VALUE self, VALUE scheme_name, VALUE class) {
109
118
  return(Qtrue);
110
119
  }
111
120
 
121
+ /*
122
+ * call-seq:
123
+ * remove_scheme
124
+ *
125
+ * No documentation available.
126
+ */
112
127
  VALUE
113
128
  input_callbacks_remove_scheme (VALUE self, VALUE scheme_name) {
114
129
  char *name;
@@ -120,7 +135,6 @@ input_callbacks_remove_scheme (VALUE self, VALUE scheme_name) {
120
135
  if (0 == first_scheme)
121
136
  return Qfalse;
122
137
 
123
- /* check the first one */
124
138
  if (!strncmp(name, first_scheme->scheme_name, first_scheme->name_len)) {
125
139
  save_scheme = first_scheme->next_scheme;
126
140
 
@@ -1,1582 +1,1566 @@
1
- /* $Id: ruby_xml_node.c 497 2008-07-22 01:33:51Z 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
- 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
- /*
24
- * call-seq:
25
- * node.base -> "uri"
26
- *
27
- * Obtain this node's base URI.
28
- */
29
- VALUE
30
- ruby_xml_node_base_get(VALUE self) {
31
- xmlNodePtr xnode;
32
- xmlChar* base_uri;
33
- VALUE result = Qnil;
34
-
35
- Data_Get_Struct(self, xmlNode, xnode);
36
-
37
- if (xnode->doc == NULL)
38
- return(result);
39
-
40
- base_uri = xmlNodeGetBase(xnode->doc, xnode);
41
- if (base_uri) {
42
- result = rb_str_new2((const char*)base_uri);
43
- xmlFree(base_uri);
44
- }
45
-
46
- return(result);
47
- }
48
-
49
-
50
- // TODO node_base_set should support setting back to nil
51
-
52
- /*
53
- * call-seq:
54
- * node.base = "uri"
55
- *
56
- * Set this node's base URI.
57
- */
58
- VALUE
59
- ruby_xml_node_base_set(VALUE self, VALUE uri) {
60
- xmlNodePtr xnode;
61
-
62
- Check_Type(uri, T_STRING);
63
- Data_Get_Struct(self, xmlNode, xnode);
64
- if (xnode->doc == NULL)
65
- return(Qnil);
66
-
67
- xmlNodeSetBase(xnode, (xmlChar*)StringValuePtr(uri));
68
- return(Qtrue);
69
- }
70
-
71
-
72
- /*
73
- * call-seq:
74
- * node.content -> "string"
75
- *
76
- * Obtain this node's content as a string.
77
- */
78
- VALUE
79
- ruby_xml_node_content_get(VALUE self) {
80
- xmlNodePtr xnode;
81
- xmlChar *content;
82
- VALUE result = Qnil;
83
-
84
- Data_Get_Struct(self, xmlNode, xnode);
85
- content = xmlNodeGetContent(xnode);
86
- if (content) {
87
- result = rb_str_new2((const char *) content);
88
- xmlFree(content);
89
- }
90
-
91
- return result;
92
- }
93
-
94
- /*
95
- * call-seq:
96
- * node.content = "string"
97
- *
98
- * Set this node's content to the specified string.
99
- */
100
- VALUE
101
- ruby_xml_node_content_set(VALUE self, VALUE content) {
102
- xmlNodePtr xnode;
103
-
104
- Check_Type(content, T_STRING);
105
- Data_Get_Struct(self, xmlNode, xnode);
106
- // XXX docs indicate need for escaping entites, need to be done? danj
107
- xmlNodeSetContent(xnode, (xmlChar*)StringValuePtr(content));
108
- return(Qtrue);
109
- }
110
-
111
-
112
- /*
113
- * call-seq:
114
- * node.content_stripped -> "string"
115
- *
116
- * Obtain this node's stripped content.
117
- *
118
- * *Deprecated*: Stripped content can be obtained via the
119
- * +content+ method.
120
- */
121
- VALUE
122
- ruby_xml_node_content_stripped_get(VALUE self) {
123
- xmlNodePtr xnode;
124
- xmlChar* content;
125
- VALUE result = Qnil;
126
-
127
- Data_Get_Struct(self, xmlNode, xnode);
128
-
129
- if (!xnode->content)
130
- return result;
131
-
132
- content = xmlNodeGetContent(xnode);
133
- if (content) {
134
- result = rb_str_new2((const char*)content);
135
- xmlFree(content);
136
- }
137
- return(result);
138
- }
139
-
140
- /*
141
- * call-seq:
142
- * node.first -> XML::Node
143
- *
144
- * Returns this node's first child node if any.
145
- */
146
- VALUE
147
- ruby_xml_node_first_get(VALUE self) {
148
- xmlNodePtr xnode;
149
-
150
- Data_Get_Struct(self, xmlNode, xnode);
151
-
152
- if (xnode->children)
153
- return(ruby_xml_node2_wrap(cXMLNode, xnode->children));
154
- else
155
- return(Qnil);
156
- }
157
-
158
-
159
- /*
160
- * underlying for child_set and child_add, difference being
161
- * former raises on implicit copy, latter does not.
162
- */
163
- VALUE
164
- ruby_xml_node_child_set_aux(VALUE self, VALUE rnode) {
165
- xmlNodePtr pnode, chld, ret;
166
-
167
- if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
168
- rb_raise(rb_eTypeError, "Must pass an XML::Node object");
169
-
170
- Data_Get_Struct(self, xmlNode, pnode);
171
- Data_Get_Struct(rnode, xmlNode, chld);
172
-
173
- if ( chld->parent != NULL || chld->doc != NULL )
174
- rb_raise(rb_eRuntimeError, "Cannot move a node from one document to another with child= or <<. First copy the node before moving it.");
175
-
176
- ret = xmlAddChild(pnode, chld);
177
- if (ret == NULL) {
178
- rb_raise(eXMLNodeFailedModify, "unable to add a child to the document");
179
- } else if ( ret==chld ) {
180
- /* child was added whole to parent and we need to return it as a new object */
181
- return ruby_xml_node2_wrap(cXMLNode,chld);
182
- }
183
- /* else */
184
- /* If it was a text node, then ret should be parent->last, so we will just return ret. */
185
- return ruby_xml_node2_wrap(cXMLNode,ret);
186
- }
187
-
188
- /*
189
- * call-seq:
190
- * node.child = node
191
- *
192
- * Set a child node for this node. Also called for <<
193
- */
194
- VALUE
195
- ruby_xml_node_child_set(VALUE self, VALUE rnode) {
196
- return ruby_xml_node_child_set_aux(self, rnode);
197
- }
198
-
199
-
200
- /*
201
- * call-seq:
202
- * node << ("string" | node) -> XML::Node
203
- *
204
- * Add the specified string or XML::Node to this node's
205
- * content.
206
- */
207
- VALUE
208
- ruby_xml_node_content_add(VALUE self, VALUE obj) {
209
- xmlNodePtr xnode;
210
- VALUE str;
211
-
212
- Data_Get_Struct(self, xmlNode, xnode);
213
- /* XXX This should only be legal for a CDATA type node, I think,
214
- * resulting in a merge of content, as if a string were passed
215
- * danj 070827
216
- */
217
- if (rb_obj_is_kind_of(obj, cXMLNode)) {
218
- ruby_xml_node_child_set(self, obj);
219
- return(self);
220
- } else if (TYPE(obj) == T_STRING) {
221
- xmlNodeAddContent(xnode, (xmlChar*)StringValuePtr(obj));
222
- return(self);
223
- } else {
224
- str = rb_obj_as_string(obj);
225
- if (NIL_P(str) || TYPE(str) != T_STRING)
226
- rb_raise(rb_eTypeError, "invalid argument: must be string or XML::Node");
227
-
228
- xmlNodeAddContent(xnode, (xmlChar*)StringValuePtr(str));
229
- return(self);
230
- }
231
- }
232
-
233
- /*
234
- * call-seq:
235
- * node.child_add(node)
236
- *
237
- * Set a child node for this node.
238
- */
239
- VALUE
240
- ruby_xml_node_child_add(VALUE self, VALUE rnode) {
241
- return ruby_xml_node_child_set_aux(self, rnode);
242
- }
243
-
244
- /*
245
- * call-seq:
246
- * node.doc -> document
247
- *
248
- * Obtain the XML::Document this node belongs to.
249
- */
250
- VALUE
251
- ruby_xml_node_doc(VALUE self) {
252
- xmlNodePtr xnode;
253
- xmlDocPtr doc=NULL;
254
-
255
- Data_Get_Struct(self, xmlNode, xnode);
256
-
257
- switch (xnode->type) {
258
- case XML_DOCUMENT_NODE:
259
- #ifdef LIBXML_DOCB_ENABLED
260
- case XML_DOCB_DOCUMENT_NODE:
261
- #endif
262
- case XML_HTML_DOCUMENT_NODE:
263
- doc = NULL;
264
- break;
265
- case XML_ATTRIBUTE_NODE:
266
- {
267
- xmlAttrPtr attr = (xmlAttrPtr) xnode;
268
- doc = attr->doc;
269
- break;
270
- }
271
- case XML_NAMESPACE_DECL:
272
- doc = NULL;
273
- break;
274
- default:
275
- doc = xnode->doc;
276
- break;
277
- }
278
-
279
- if (doc == NULL)
280
- return(Qnil);
281
-
282
- if ( doc->_private == NULL )
283
- rb_raise(rb_eRuntimeError,"existing document object has no ruby-instance");
284
-
285
- return (VALUE)doc->_private;
286
- }
287
-
288
-
289
- /*
290
- * call-seq:
291
- * node.dump -> (true|nil)
292
- *
293
- * Dump this node to stdout.
294
- */
295
- VALUE
296
- ruby_xml_node_dump(VALUE self) {
297
- xmlNodePtr xnode;
298
- xmlBufferPtr buf;
299
-
300
- Data_Get_Struct(self, xmlNode, xnode);
301
-
302
- if (xnode->doc == NULL)
303
- return(Qnil);
304
-
305
- buf = xmlBufferCreate();
306
- xmlNodeDump(buf, xnode->doc, xnode, 0, 1);
307
- xmlBufferDump(stdout, buf);
308
- xmlBufferFree(buf);
309
- return(Qtrue);
310
- }
311
-
312
-
313
- /*
314
- * call-seq:
315
- * node.debug_dump -> (true|nil)
316
- *
317
- * Dump this node to stdout, including any debugging
318
- * information.
319
- */
320
- VALUE
321
- ruby_xml_node_debug_dump(VALUE self) {
322
- xmlNodePtr xnode;
323
- Data_Get_Struct(self, xmlNode, xnode);
324
-
325
- if (xnode->doc == NULL)
326
- return(Qnil);
327
-
328
- xmlElemDump(stdout, xnode->doc, xnode);
329
- return(Qtrue);
330
- }
331
-
332
- /*
333
- * call-seq:
334
- * node.each -> XML::Node
335
- *
336
- * Iterates over this node's children, including text
337
- * nodes, element nodes, etc. If you wish to iterate
338
- * only over child elements, use XML::Node#each_element.
339
- *
340
- * doc = XML::Document.new('model/books.xml')
341
- * doc.root.each {|node| puts node}
342
- */
343
- VALUE
344
- ruby_xml_node_each(VALUE self) {
345
- xmlNodePtr xnode;
346
- xmlNodePtr xchild;
347
- Data_Get_Struct(self, xmlNode, xnode);
348
-
349
- xchild = xnode->children;
350
-
351
- while (xchild) {
352
- rb_yield(ruby_xml_node2_wrap(cXMLNode, xchild));
353
- xchild = xchild->next;
354
- }
355
- return Qnil;
356
- }
357
-
358
-
359
- /*
360
- * call-seq:
361
- * node.empty? -> (true|false)
362
- *
363
- * Determine whether this node is empty.
364
- */
365
- VALUE
366
- ruby_xml_node_empty_q(VALUE self) {
367
- xmlNodePtr xnode;
368
- Data_Get_Struct(self, xmlNode, xnode);
369
- if (xnode == NULL)
370
- return(Qnil);
371
-
372
- return((xmlIsBlankNode(xnode) == 1) ? Qtrue : Qfalse);
373
- }
374
-
375
-
376
- VALUE ruby_xml_node_to_s(VALUE self);
377
-
378
- /*
379
- * call-seq:
380
- * node.eql?(other_node) => (true|false)
381
- *
382
- * Test equality between the two nodes. Two nodes are equal
383
- * if they are the same node or have the same XML representation.*/
384
- VALUE
385
- ruby_xml_node_eql_q(VALUE self, VALUE other) {
386
- if (self == other)
387
- {
388
- return Qtrue;
389
- }
390
- else if NIL_P(other)
391
- {
392
- return Qfalse;
393
- }
394
- else
395
- {
396
- VALUE self_xml;
397
- VALUE other_xml;
398
-
399
- if (rb_obj_is_kind_of(other, cXMLNode) == Qfalse)
400
- rb_raise(rb_eTypeError, "Nodes can only be compared against other nodes");
401
-
402
- self_xml = ruby_xml_node_to_s(self);
403
- other_xml = ruby_xml_node_to_s(other);
404
- return(rb_funcall(self_xml, rb_intern("=="), 1, other_xml));
405
- }
406
- }
407
-
408
- /*
409
- * call-seq:
410
- * XML::Node.new_cdata(content = nil) -> XML::Node
411
- *
412
- * Create a new #CDATA node, optionally setting
413
- * the node's content.
414
- */
415
- VALUE
416
- ruby_xml_node_new_cdata(int argc, VALUE *argv, VALUE class) {
417
- xmlNodePtr xnode;
418
- VALUE str=Qnil;
419
-
420
- switch(argc) {
421
- case 1:
422
- str = argv[0];
423
- Check_Type(str, T_STRING);
424
- if (!NIL_P(str)) {
425
- xnode = xmlNewCDataBlock(NULL, (xmlChar*)StringValuePtr(str), xmlStrlen((xmlChar*)StringValuePtr(str)));
426
- } else {
427
- xnode = xmlNewCDataBlock(NULL, NULL , 0);
428
- }
429
-
430
- if (xnode == NULL)
431
- return(Qnil);
432
-
433
- return ruby_xml_node2_wrap(class,xnode);
434
-
435
- default:
436
- rb_raise(rb_eArgError, "wrong number of arguments (1)");
437
- }
438
-
439
- // not reached
440
- return(Qnil);
441
- }
442
-
443
-
444
- /*
445
- * call-seq:
446
- * XML::Node.new_comment(content = nil) -> XML::Node
447
- *
448
- * Create a new comment node, optionally setting
449
- * the node's content.
450
- *
451
- */
452
- VALUE
453
- ruby_xml_node_new_comment(int argc, VALUE *argv, VALUE class) {
454
- xmlNodePtr xnode;
455
- VALUE str=Qnil;
456
-
457
- switch(argc) {
458
- case 1:
459
- str = argv[0];
460
- Check_Type(str, T_STRING);
461
- // TODO xmlNewComment wrongly? adds \n before and after the comment
462
- if (!NIL_P(str)) {
463
- xnode = xmlNewComment((xmlChar*)StringValuePtr(str));
464
- } else {
465
- xnode = xmlNewComment(NULL);
466
- }
467
-
468
- if (xnode == NULL)
469
- return(Qnil);
470
-
471
- return ruby_xml_node2_wrap(class,xnode);
472
-
473
- default:
474
- rb_raise(rb_eArgError, "wrong number of arguments (1)");
475
- }
476
-
477
- // not reached
478
- return(Qnil);
479
- }
480
-
481
-
482
- /*
483
- * call-seq:
484
- * node.lang -> "string"
485
- *
486
- * Obtain the language set for this node, if any.
487
- * This is set in XML via the xml:lang attribute.
488
- */
489
- VALUE
490
- ruby_xml_node_lang_get(VALUE self) {
491
- xmlNodePtr xnode;
492
- xmlChar *lang;
493
- VALUE result = Qnil;
494
-
495
- Data_Get_Struct(self, xmlNode, xnode);
496
- lang = xmlNodeGetLang(xnode);
497
-
498
- if (lang) {
499
- result = rb_str_new2((const char*)lang);
500
- xmlFree(lang);
501
- }
502
-
503
- return(result);
504
- }
505
-
506
-
507
- // TODO node_lang_set should support setting back to nil
508
-
509
- /*
510
- * call-seq:
511
- * node.lang = "string"
512
- *
513
- * Set the language for this node. This affects the value
514
- * of the xml:lang attribute.
515
- */
516
- VALUE
517
- ruby_xml_node_lang_set(VALUE self, VALUE lang) {
518
- xmlNodePtr xnode;
519
-
520
- Check_Type(lang, T_STRING);
521
- Data_Get_Struct(self, xmlNode, xnode);
522
- xmlNodeSetLang(xnode, (xmlChar*)StringValuePtr(lang));
523
-
524
- return(Qtrue);
525
- }
526
-
527
-
528
- /*
529
- * call-seq:
530
- * node.last -> XML::Node
531
- *
532
- * Obtain the last child node of this node, if any.
533
- */
534
- VALUE
535
- ruby_xml_node_last_get(VALUE self) {
536
- xmlNodePtr xnode;
537
-
538
- Data_Get_Struct(self, xmlNode, xnode);
539
-
540
- if (xnode->last)
541
- return(ruby_xml_node2_wrap(cXMLNode, xnode->last));
542
- else
543
- return(Qnil);
544
- }
545
-
546
- /*
547
- * call-seq:
548
- * node.line_num -> num
549
- *
550
- * Obtain the line number (in the XML document) that this
551
- * node was read from. If +default_line_numbers+ is set
552
- * false (the default), this method returns zero.
553
- */
554
- VALUE
555
- ruby_xml_node_line_num(VALUE self) {
556
- xmlNodePtr xnode;
557
- long line_num;
558
- Data_Get_Struct(self, xmlNode, xnode);
559
-
560
- if (!xmlLineNumbersDefaultValue)
561
- rb_warn("Line numbers were not retained: use XML::Parser::default_line_numbers=true");
562
-
563
- line_num = xmlGetLineNo(xnode);
564
- if (line_num == -1)
565
- return(Qnil);
566
- else
567
- return(INT2NUM((long)line_num));
568
- }
569
-
570
-
571
- /*
572
- * call-seq:
573
- * node.xlink? -> (true|false)
574
- *
575
- * Determine whether this node is an xlink node.
576
- */
577
- VALUE
578
- ruby_xml_node_xlink_q(VALUE self) {
579
- xmlNodePtr xnode;
580
- xlinkType xlt;
581
-
582
- Data_Get_Struct(self, xmlNode, xnode);
583
- xlt = xlinkIsLink(xnode->doc, xnode);
584
-
585
- if (xlt == XLINK_TYPE_NONE)
586
- return(Qfalse);
587
- else
588
- return(Qtrue);
589
- }
590
-
591
-
592
- /*
593
- * call-seq:
594
- * node.xlink_type -> num
595
- *
596
- * Obtain the type identifier for this xlink, if applicable.
597
- * If this is not an xlink node (see +xlink?+), will return
598
- * nil.
599
- */
600
- VALUE
601
- ruby_xml_node_xlink_type(VALUE self) {
602
- xmlNodePtr xnode;
603
- xlinkType xlt;
604
-
605
- Data_Get_Struct(self, xmlNode, xnode);
606
- xlt = xlinkIsLink(xnode->doc, xnode);
607
-
608
- if (xlt == XLINK_TYPE_NONE)
609
- return(Qnil);
610
- else
611
- return(INT2NUM(xlt));
612
- }
613
-
614
-
615
- /*
616
- * call-seq:
617
- * node.xlink_type_name -> "string"
618
- *
619
- * Obtain the type name for this xlink, if applicable.
620
- * If this is not an xlink node (see +xlink?+), will return
621
- * nil.
622
- */
623
- VALUE
624
- ruby_xml_node_xlink_type_name(VALUE self) {
625
- xmlNodePtr xnode;
626
- xlinkType xlt;
627
-
628
- Data_Get_Struct(self, xmlNode, xnode);
629
- xlt = xlinkIsLink(xnode->doc, xnode);
630
-
631
- switch(xlt) {
632
- case XLINK_TYPE_NONE:
633
- return(Qnil);
634
- case XLINK_TYPE_SIMPLE:
635
- return(rb_str_new2("simple"));
636
- case XLINK_TYPE_EXTENDED:
637
- return(rb_str_new2("extended"));
638
- case XLINK_TYPE_EXTENDED_SET:
639
- return(rb_str_new2("extended_set"));
640
- default:
641
- rb_fatal("Unknowng xlink type, %d", xlt);
642
- }
643
- }
644
-
645
- /*
646
- * call-seq:
647
- * node.name -> "string"
648
- *
649
- * Obtain this node's name.
650
- */
651
- VALUE
652
- ruby_xml_node_name_get(VALUE self) {
653
- xmlNodePtr xnode;
654
- const xmlChar *name;
655
-
656
- Data_Get_Struct(self, xmlNode, xnode);
657
-
658
- switch (xnode->type) {
659
- case XML_DOCUMENT_NODE:
660
- #ifdef LIBXML_DOCB_ENABLED
661
- case XML_DOCB_DOCUMENT_NODE:
662
- #endif
663
- case XML_HTML_DOCUMENT_NODE:
664
- {
665
- xmlDocPtr doc = (xmlDocPtr) xnode;
666
- name = doc->URL;
667
- break;
668
- }
669
- case XML_ATTRIBUTE_NODE:
670
- {
671
- xmlAttrPtr attr = (xmlAttrPtr) xnode;
672
- name = attr->name;
673
- break;
674
- }
675
- case XML_NAMESPACE_DECL:
676
- {
677
- xmlNsPtr ns = (xmlNsPtr) xnode;
678
- name = ns->prefix;
679
- break;
680
- }
681
- default:
682
- name = xnode->name;
683
- break;
684
- }
685
-
686
- if (xnode->name == NULL)
687
- return(Qnil);
688
- else
689
- return(rb_str_new2((const char*)name));
690
- }
691
-
692
-
693
- /*
694
- * call-seq:
695
- * node.name = "string"
696
- *
697
- * Set this node's name.
698
- */
699
- VALUE
700
- ruby_xml_node_name_set(VALUE self, VALUE name) {
701
- xmlNodePtr xnode;
702
-
703
- Check_Type(name, T_STRING);
704
- Data_Get_Struct(self, xmlNode, xnode);
705
- xmlNodeSetName(xnode, (xmlChar*)StringValuePtr(name));
706
- return(Qtrue);
707
- }
708
-
709
-
710
- /*
711
- * call-seq:
712
- * node.namespace -> [namespace, ..., namespace]
713
- *
714
- * Obtain an array of +XML::NS+ objects representing
715
- * this node's xmlns attributes
716
- */
717
- VALUE
718
- ruby_xml_node_namespace_get(VALUE self) {
719
- xmlNodePtr xnode;
720
- xmlNsPtr *nsList, *cur;
721
- VALUE arr, ns;
722
-
723
- Data_Get_Struct(self, xmlNode, xnode);
724
- if (xnode == NULL)
725
- return(Qnil);
726
-
727
- nsList = xmlGetNsList(xnode->doc, xnode);
728
-
729
- if (nsList == NULL)
730
- return(Qnil);
731
-
732
- arr = rb_ary_new();
733
- for (cur = nsList; *cur != NULL; cur++) {
734
- ns = ruby_xml_ns_wrap(*cur);
735
- if (ns == Qnil)
736
- continue;
737
- else
738
- rb_ary_push(arr, ns);
739
- }
740
- xmlFree(nsList);
741
-
742
- return(arr);
743
- }
744
-
745
-
746
- /*
747
- * call-seq:
748
- * node.namespace_node -> namespace.
749
- *
750
- * Obtain this node's namespace node.
751
- */
752
- VALUE
753
- ruby_xml_node_namespace_get_node(VALUE self) {
754
- xmlNodePtr xnode;
755
-
756
- Data_Get_Struct(self, xmlNode, xnode);
757
- if (xnode->ns == NULL)
758
- return(Qnil);
759
- else
760
- return ruby_xml_ns_wrap(xnode->ns);
761
- }
762
-
763
- // TODO namespace_set can take varargs (in fact, must if used
764
- // with strings), but I cannot see how you can call
765
- // that version, apart from with 'send'
766
- //
767
- // Would sure be nice to support foo.namespace['foo'] = 'bar'
768
- // but maybe that's not practical...
769
-
770
- /*
771
- * call-seq:
772
- * node.namespace = namespace
773
- *
774
- * Add the specified XML::NS object to this node's xmlns attributes.
775
- */
776
- VALUE
777
- ruby_xml_node_namespace_set(int argc, VALUE *argv, VALUE self) {
778
- VALUE rns, rprefix;
779
- xmlNodePtr xnode;
780
- xmlNsPtr xns;
781
- char *cp, *href;
782
-
783
- Data_Get_Struct(self, xmlNode, xnode);
784
- switch (argc) {
785
- case 1:
786
- rns = argv[0];
787
- if (TYPE(rns) == T_STRING) {
788
- cp = strchr(StringValuePtr(rns), (int)':');
789
- if (cp == NULL) {
790
- rprefix = rns;
791
- href = NULL;
792
- } else {
793
- rprefix = rb_str_new(StringValuePtr(rns), (int)((long)cp - (long)StringValuePtr(rns)));
794
- href = &cp[1]; /* skip the : */
795
- }
796
- } else if (rb_obj_is_kind_of(rns, cXMLNS) == Qtrue) {
797
- Data_Get_Struct(self, xmlNs, xns);
798
- xmlSetNs(xnode, xns);
799
- return(rns);
800
- } else
801
- rb_raise(rb_eTypeError, "must pass a string or an XML::Ns object");
802
-
803
- /* Fall through to next case because when argc == 1, we need to
804
- * manually setup the additional args unless the arg passed is of
805
- * cXMLNS type */
806
- case 2:
807
- /* Don't want this code run in the fall through case */
808
- if (argc == 2) {
809
- rprefix = argv[0];
810
- href = StringValuePtr(argv[1]);
811
- }
812
-
813
- xns = xmlNewNs(xnode, (xmlChar*)href, (xmlChar*)StringValuePtr(rprefix));
814
- if (xns == NULL)
815
- rb_raise(eXMLNodeSetNamespace, "unable to set the namespace");
816
- else
817
- return ruby_xml_ns_wrap(xns);
818
- break;
819
-
820
- default:
821
- rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
822
- }
823
-
824
- /* can't get here */
825
- return(Qnil);
826
- }
827
-
828
-
829
- /*
830
- * memory2 implementation: xmlNode->_private holds a reference
831
- * to the wrapping ruby object VALUE when there is one.
832
- * traversal for marking is upward, and top levels are marked
833
- * through and lower level mark entry.
834
- *
835
- * All ruby retrieval for an xml
836
- * node will result in the same ruby instance. When all handles to them
837
- * go out of scope, then ruby_xfree gets called and _private is set to NULL.
838
- * If the xmlNode has no parent or document, then call xmlFree.
839
- */
840
- void
841
- ruby_xml_node2_free(xmlNodePtr xnode) {
842
-
843
- if (xnode != NULL) {
844
- xnode->_private=NULL;
845
-
846
- if (xnode->doc==NULL && xnode->parent==NULL) {
847
- #ifdef NODE_DEBUG
848
- fprintf(stderr,"ruby_xml_node2_free ruby_xfree rxn=0x%x xn=0x%x o=0x%x\n",(long)rxn,(long)xnode,(long)xnode->_private);
849
- #endif
850
- xmlFreeNode(xnode);
851
- }
852
- }
853
- }
854
-
855
- void
856
- ruby_xml_node_mark_common(xmlNodePtr xnode) {
857
- if (xnode->parent == NULL ) {
858
- #ifdef NODE_DEBUG
859
- fprintf(stderr,"mark no parent r=0x%x *n=0x%x\n",rxn,node);
860
- #endif
861
- } else if (xnode->doc != NULL ) {
862
- if (xnode->doc->_private == NULL) {
863
- rb_bug("XmlNode Doc is not bound! (%s:%d)",
864
- __FILE__,__LINE__);
865
- }
866
- rb_gc_mark((VALUE)xnode->doc->_private);
867
- } else {
868
- while (xnode->parent != NULL )
869
- xnode = xnode->parent;
870
- if (xnode->_private == NULL )
871
- rb_warning("XmlNode Root Parent is not bound! (%s:%d)",
872
- __FILE__,__LINE__);
873
- else {
874
- #ifdef NODE_DEBUG
875
- 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);
876
- #endif
877
- rb_gc_mark((VALUE)xnode->_private);
878
- }
879
- }
880
- }
881
-
882
- void
883
- ruby_xml_node2_mark(xmlNodePtr xnode) {
884
- if (xnode == NULL ) return;
885
-
886
- if (xnode->_private == NULL ) {
887
- rb_warning("XmlNode is not bound! (%s:%d)",
888
- __FILE__,__LINE__);
889
- return;
890
- }
891
-
892
- ruby_xml_node_mark_common(xnode);
893
- }
894
-
895
- VALUE
896
- ruby_xml_node2_wrap(VALUE class, xmlNodePtr xnode)
897
- {
898
- VALUE obj;
899
-
900
- // This node is already wrapped
901
- if (xnode->_private != NULL) {
902
- #ifdef NODE_DEBUG
903
- Data_Get_Struct((VALUE)xnode->_private,ruby_xml_node,rxn);
904
- fprintf(stderr,"re-wrap rn=0x%x n*=0x%x\n",(long)rxn,(long)xnode);
905
- #endif
906
- return (VALUE)xnode->_private;
907
- }
908
-
909
- obj=Data_Wrap_Struct(class,
910
- ruby_xml_node2_mark, ruby_xml_node2_free,
911
- xnode);
912
-
913
- xnode->_private=(void*)obj;
914
- #ifdef NODE_DEBUG
915
- fprintf(stderr,"wrap rn=0x%x n*=0x%x d*=0x%x\n",
916
- (long)rxn,(long)xnode,xnode->doc);
917
- #endif
918
- return obj;
919
- }
920
-
921
- VALUE
922
- ruby_xml_node2_new_native(VALUE class, VALUE ns, VALUE name)
923
- {
924
- VALUE obj;
925
- xmlNodePtr xnode;
926
- xmlNsPtr xns=NULL;
927
-
928
- if ( ! NIL_P(ns) ) {
929
- Data_Get_Struct(ns,xmlNs,xns);
930
- }
931
- xnode=xmlNewNode(xns,(xmlChar*)StringValuePtr(name));
932
- xnode->_private=NULL;
933
-
934
- obj= ruby_xml_node2_wrap(class,xnode);
935
-
936
- rb_obj_call_init(obj,0,NULL);
937
- return obj;
938
- }
939
-
940
- VALUE
941
- ruby_xml_node2_new_string(VALUE class, VALUE ns, VALUE name, VALUE val)
942
- {
943
- VALUE obj;
944
- obj=ruby_xml_node2_new_native(class,ns,name);
945
- if ( ! NIL_P(val) ) {
946
- if ( TYPE(val) != T_STRING )
947
- val=rb_obj_as_string(val);
948
- ruby_xml_node_content_set(obj,val);
949
- }
950
- return obj;
951
- }
952
- /*
953
- * call-seq:
954
- * XML::Node.new(name, content = nil) -> XML::Node
955
- * XML::Node.new_element(name, content = nil) -> XML::Node
956
- *
957
- * Create a new element node with the specified name, optionally setting
958
- * the node's content.
959
- * backward compatibility for <.5 new
960
- */
961
- VALUE
962
- ruby_xml_node2_new_string_bc(int argc, VALUE *argv, VALUE class)
963
- {
964
- VALUE content=Qnil;
965
- VALUE name=Qnil;
966
- switch(argc) {
967
- case 2:
968
- content=argv[1];
969
- if ( TYPE(content) != T_STRING)
970
- content=rb_obj_as_string(content);
971
-
972
- case 1:
973
- name=check_string_or_symbol( argv[0] );
974
- return ruby_xml_node2_new_string(class,Qnil,name,content);
975
-
976
- default:
977
- rb_raise(rb_eArgError, "wrong number of arguments (1 or 2) given %d",argc);
978
- }
979
- }
980
-
981
- /*
982
- * call-seq:
983
- * node.next -> XML::Node
984
- *
985
- * Obtain the next sibling node, if any.
986
- */
987
- VALUE
988
- ruby_xml_node_next_get(VALUE self) {
989
- xmlNodePtr xnode;
990
-
991
- Data_Get_Struct(self, xmlNode, xnode);
992
-
993
- if (xnode->next)
994
- return(ruby_xml_node2_wrap(cXMLNode, xnode->next));
995
- else
996
- return(Qnil);
997
- }
998
-
999
-
1000
- /*
1001
- * call-seq:
1002
- * node.next = node
1003
- *
1004
- * Insert the specified node as this node's next sibling.
1005
- */
1006
- VALUE
1007
- ruby_xml_node_next_set(VALUE self, VALUE rnode) {
1008
- xmlNodePtr cnode, pnode, ret;
1009
-
1010
- if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
1011
- rb_raise(rb_eTypeError, "Must pass an XML::Node object");
1012
-
1013
- Data_Get_Struct(self, xmlNode, pnode);
1014
- Data_Get_Struct(rnode, xmlNode, cnode);
1015
-
1016
- ret = xmlAddNextSibling(pnode, cnode);
1017
- if (ret == NULL)
1018
- rb_raise(eXMLNodeFailedModify, "unable to add a sibling to the document");
1019
-
1020
- return(ruby_xml_node2_wrap(cXMLNode, ret));
1021
- }
1022
-
1023
-
1024
- /*
1025
- * call-seq:
1026
- * node.ns? -> (true|false)
1027
- *
1028
- * Determine whether this node has a namespace.
1029
- */
1030
- VALUE
1031
- ruby_xml_node_ns_q(VALUE self) {
1032
- xmlNodePtr xnode;
1033
- Data_Get_Struct(self, xmlNode, xnode);
1034
- if (xnode->ns == NULL)
1035
- return(Qfalse);
1036
- else
1037
- return(Qtrue);
1038
- }
1039
-
1040
- /*
1041
- * call-seq:
1042
- * node.ns_def? -> (true|false)
1043
- *
1044
- * Obtain an array of +XML::NS+ objects representing
1045
- * this node's xmlns attributes
1046
- */
1047
- VALUE
1048
- ruby_xml_node_ns_def_q(VALUE self) {
1049
- xmlNodePtr xnode;
1050
- Data_Get_Struct(self, xmlNode, xnode);
1051
- if (xnode->nsDef == NULL)
1052
- return(Qfalse);
1053
- else
1054
- return(Qtrue);
1055
- }
1056
-
1057
-
1058
- /*
1059
- * call-seq:
1060
- * node.ns_def -> namespace
1061
- *
1062
- * Obtain this node's default namespace.
1063
- */
1064
- VALUE
1065
- ruby_xml_node_ns_def_get(VALUE self) {
1066
- xmlNodePtr xnode;
1067
- Data_Get_Struct(self, xmlNode, xnode);
1068
- if (xnode->nsDef == NULL)
1069
- return(Qnil);
1070
- else
1071
- return(ruby_xml_ns_wrap(xnode->nsDef));
1072
- }
1073
-
1074
-
1075
- /*
1076
- * call-seq:
1077
- * node.parent -> XML::Node
1078
- *
1079
- * Obtain this node's parent node, if any.
1080
- */
1081
- VALUE
1082
- ruby_xml_node_parent_get(VALUE self) {
1083
- xmlNodePtr xnode;
1084
-
1085
- Data_Get_Struct(self, xmlNode, xnode);
1086
-
1087
- if (xnode->parent)
1088
- return(ruby_xml_node2_wrap(cXMLNode, xnode->parent));
1089
- else
1090
- return(Qnil);
1091
- }
1092
-
1093
-
1094
- /*
1095
- * call-seq:
1096
- * node.path -> path
1097
- *
1098
- * Obtain this node's path.
1099
- */
1100
- VALUE
1101
- ruby_xml_node_path(VALUE self) {
1102
- xmlNodePtr xnode;
1103
- xmlChar *path;
1104
-
1105
- Data_Get_Struct(self, xmlNode, xnode);
1106
- path = xmlGetNodePath(xnode);
1107
-
1108
- if (path == NULL)
1109
- return(Qnil);
1110
- else
1111
- return(rb_str_new2((const char*)path));
1112
- }
1113
-
1114
-
1115
- /*
1116
- * call-seq:
1117
- * node.pointer -> XML::Node_set
1118
- *
1119
- * Evaluates an XPointer expression relative to this node.
1120
- */
1121
- VALUE
1122
- ruby_xml_node_pointer(VALUE self, VALUE xptr_str) {
1123
- return(ruby_xml_xpointer_point2(self, xptr_str));
1124
- }
1125
-
1126
-
1127
- /*
1128
- * call-seq:
1129
- * node.prev -> XML::Node
1130
- *
1131
- * Obtain the previous sibling, if any.
1132
- */
1133
- VALUE
1134
- ruby_xml_node_prev_get(VALUE self) {
1135
- xmlNodePtr xnode;
1136
- xmlNodePtr node;
1137
- Data_Get_Struct(self, xmlNode, xnode);
1138
-
1139
- switch (xnode->type) {
1140
- case XML_DOCUMENT_NODE:
1141
- #ifdef LIBXML_DOCB_ENABLED
1142
- case XML_DOCB_DOCUMENT_NODE:
1143
- #endif
1144
- case XML_HTML_DOCUMENT_NODE:
1145
- case XML_NAMESPACE_DECL:
1146
- node = NULL;
1147
- break;
1148
- case XML_ATTRIBUTE_NODE:
1149
- {
1150
- xmlAttrPtr attr = (xmlAttrPtr) xnode;
1151
- node = (xmlNodePtr) attr->prev;
1152
- }
1153
- break;
1154
- default:
1155
- node = xnode->prev;
1156
- break;
1157
- }
1158
-
1159
- if (node == NULL)
1160
- return(Qnil);
1161
- else
1162
- return(ruby_xml_node2_wrap(cXMLNode, node));
1163
- }
1164
-
1165
-
1166
- /*
1167
- * call-seq:
1168
- * node.prev = node
1169
- *
1170
- * Insert the specified node as this node's previous sibling.
1171
- */
1172
- VALUE
1173
- ruby_xml_node_prev_set(VALUE self, VALUE rnode) {
1174
- xmlNodePtr cnode, pnode, ret;
1175
-
1176
- if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
1177
- rb_raise(rb_eTypeError, "Must pass an XML::Node object");
1178
-
1179
- Data_Get_Struct(self, xmlNode, pnode);
1180
- Data_Get_Struct(rnode, xmlNode, cnode);
1181
-
1182
- ret = xmlAddPrevSibling(pnode, cnode);
1183
- if (ret == NULL)
1184
- rb_raise(eXMLNodeFailedModify, "unable to add a sibling to the document");
1185
-
1186
- return(ruby_xml_node2_wrap(cXMLNode, ret));
1187
- }
1188
-
1189
- /*
1190
- * call-seq:
1191
- * node.attributes -> attributes
1192
- *
1193
- * Returns the XML::Attributes for this node.
1194
- */
1195
- VALUE
1196
- ruby_xml_node_attributes_get(VALUE self) {
1197
- xmlNodePtr xnode;
1198
-
1199
- Data_Get_Struct(self, xmlNode, xnode);
1200
- return ruby_xml_attributes_new(xnode);
1201
- }
1202
-
1203
- /*
1204
- * call-seq:
1205
- * node.property("name") -> "string"
1206
- * node["name"] -> "string"
1207
- *
1208
- * Obtain the named property.
1209
- */
1210
- VALUE
1211
- ruby_xml_node_property_get(VALUE self, VALUE name) {
1212
- VALUE attributes = ruby_xml_node_attributes_get(self);
1213
- return ruby_xml_attributes_attribute_get(attributes, name);
1214
- }
1215
-
1216
- /*
1217
- * call-seq:
1218
- * node["name"] = "string"
1219
- *
1220
- * Set the named property.
1221
- */
1222
- VALUE
1223
- ruby_xml_node_property_set(VALUE self, VALUE name, VALUE value) {
1224
- VALUE attributes = ruby_xml_node_attributes_get(self);
1225
- return ruby_xml_attributes_attribute_set(attributes, name, value);
1226
- }
1227
-
1228
-
1229
- /*
1230
- * call-seq:
1231
- * node.remove! -> nil
1232
- *
1233
- * Removes this node from it's parent.
1234
- */
1235
- VALUE
1236
- ruby_xml_node_remove_ex(VALUE self) {
1237
- xmlNodePtr xnode;
1238
- Data_Get_Struct(self, xmlNode, xnode);
1239
- xmlUnlinkNode(xnode);
1240
- return(Qnil);
1241
- }
1242
-
1243
-
1244
- /*
1245
- * call-seq:
1246
- * node.search_href -> namespace
1247
- *
1248
- * Search for a namespace by href.
1249
- */
1250
- VALUE
1251
- ruby_xml_node_search_href(VALUE self, VALUE href) {
1252
- xmlNodePtr xnode;
1253
-
1254
- Check_Type(href, T_STRING);
1255
- Data_Get_Struct(self, xmlNode, xnode);
1256
- return(ruby_xml_ns_wrap(xmlSearchNsByHref(xnode->doc, xnode,
1257
- (xmlChar*)StringValuePtr(href))));
1258
- }
1259
-
1260
-
1261
- /*
1262
- * call-seq:
1263
- * node.search_ns -> namespace
1264
- *
1265
- * Search for a namespace by namespace.
1266
- */
1267
- VALUE
1268
- ruby_xml_node_search_ns(VALUE self, VALUE ns) {
1269
- xmlNodePtr xnode;
1270
-
1271
- Check_Type(ns, T_STRING);
1272
- Data_Get_Struct(self, xmlNode, xnode);
1273
- return(ruby_xml_ns_wrap(xmlSearchNs(xnode->doc, xnode,
1274
- (xmlChar*)StringValuePtr(ns))));
1275
- }
1276
-
1277
-
1278
- /*
1279
- * call-seq:
1280
- * node.sibling(node) -> XML::Node
1281
- *
1282
- * Add the specified node as a sibling of this node.
1283
- */
1284
- VALUE
1285
- ruby_xml_node_sibling_set(VALUE self, VALUE rnode) {
1286
- xmlNodePtr cnode, pnode, ret;
1287
- VALUE obj;
1288
-
1289
- if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
1290
- rb_raise(rb_eTypeError, "Must pass an XML::Node object");
1291
-
1292
- Data_Get_Struct(self, xmlNode, pnode);
1293
- Data_Get_Struct(rnode, xmlNode, cnode);
1294
-
1295
- ret = xmlAddSibling(pnode, cnode);
1296
- if (ret == NULL)
1297
- rb_raise(eXMLNodeFailedModify, "unable to add a sibling to the document");
1298
- if (ret->_private==NULL)
1299
- obj=ruby_xml_node2_wrap(cXMLNode,ret);
1300
- else
1301
- obj=(VALUE)ret->_private;
1302
-
1303
- return obj;
1304
- }
1305
-
1306
-
1307
- /*
1308
- * call-seq:
1309
- * node.space_preserve -> (true|false)
1310
- *
1311
- * Determine whether this node preserves whitespace.
1312
- */
1313
- VALUE
1314
- ruby_xml_node_space_preserve_get(VALUE self) {
1315
- xmlNodePtr xnode;
1316
-
1317
- Data_Get_Struct(self, xmlNode, xnode);
1318
- return(INT2NUM(xmlNodeGetSpacePreserve(xnode)));
1319
- }
1320
-
1321
-
1322
- /*
1323
- * call-seq:
1324
- * node.space_preserve = true|false
1325
- *
1326
- * Control whether this node preserves whitespace.
1327
- */
1328
- VALUE
1329
- ruby_xml_node_space_preserve_set(VALUE self, VALUE bool) {
1330
- xmlNodePtr xnode;
1331
- Data_Get_Struct(self, xmlNode, xnode);
1332
-
1333
- if (TYPE(bool) == T_FALSE)
1334
- xmlNodeSetSpacePreserve(xnode, 1);
1335
- else
1336
- xmlNodeSetSpacePreserve(xnode, 0);
1337
-
1338
- return(Qnil);
1339
- }
1340
-
1341
- /*
1342
- * call-seq:
1343
- * node.to_s -> "string"
1344
- *
1345
- * Coerce this node to a string representation of
1346
- * it's XML.
1347
- */
1348
- VALUE
1349
- ruby_xml_node_to_s(VALUE self) {
1350
- xmlNodePtr xnode;
1351
- xmlBufferPtr buf;
1352
- VALUE result;
1353
-
1354
- Data_Get_Struct(self, xmlNode, xnode);
1355
- buf = xmlBufferCreate();
1356
- xmlNodeDump(buf, xnode->doc, xnode, 0, 1);
1357
- result = rb_str_new2((const char*)buf->content);
1358
-
1359
- xmlBufferFree(buf);
1360
- return result;
1361
- }
1362
-
1363
-
1364
- /*
1365
- * call-seq:
1366
- * node.type -> num
1367
- *
1368
- * Obtain this node's type identifier.
1369
- */
1370
- VALUE
1371
- ruby_xml_node_type(VALUE self) {
1372
- xmlNodePtr xnode;
1373
- Data_Get_Struct(self, xmlNode, xnode);
1374
- return(INT2NUM(xnode->type));
1375
- }
1376
-
1377
-
1378
-
1379
-
1380
- /*
1381
- * call-seq:
1382
- * node.copy -> XML::Node
1383
- *
1384
- * Creates a copy of this node. To create a
1385
- * shallow copy set the deep parameter to false.
1386
- * To create a deep copy set the deep parameter
1387
- * to true.
1388
- *
1389
- */
1390
- VALUE
1391
- ruby_xml_node_copy(VALUE self, VALUE deep) {
1392
- xmlNodePtr xnode;
1393
- xmlNodePtr xcopy;
1394
- int recursive = (deep==Qnil || deep==Qfalse) ? 0 : 1;
1395
- Data_Get_Struct(self, xmlNode, xnode);
1396
-
1397
- xcopy = xmlCopyNode(xnode, recursive);
1398
-
1399
- if (xcopy)
1400
- return ruby_xml_node2_wrap(cXMLNode, xcopy);
1401
- else
1402
- return Qnil;
1403
- }
1404
-
1405
- /*
1406
- * call-seq:
1407
- * XML::Node.new_text(content = nil) -> XML::Node
1408
- *
1409
- * Create a new text node, optionally setting
1410
- * the node's content.
1411
- *
1412
- */
1413
- VALUE
1414
- ruby_xml_node_new_text(VALUE class, VALUE text)
1415
- {
1416
- VALUE obj;
1417
- xmlNodePtr xnode;
1418
-
1419
- if ( NIL_P(text) )
1420
- return Qnil;
1421
-
1422
- if (TYPE(text) != T_STRING )
1423
- rb_raise(rb_eTypeError, "requires string argument");
1424
-
1425
- xnode=xmlNewText((xmlChar*)STR2CSTR(text));
1426
- if ( xnode == NULL )
1427
- return Qnil;
1428
-
1429
- obj=ruby_xml_node2_wrap(class,xnode);
1430
- rb_obj_call_init(obj,0,NULL);
1431
- return obj;
1432
- }
1433
-
1434
- void
1435
- ruby_xml_node_registerNode(xmlNodePtr node)
1436
- {
1437
- node->_private=NULL;
1438
- }
1439
-
1440
- void
1441
- ruby_xml_node_deregisterNode(xmlNodePtr xnode)
1442
- {
1443
- VALUE node;
1444
-
1445
- if (xnode->_private==NULL ) return;
1446
- node = (VALUE)xnode->_private;
1447
- DATA_PTR(node) = NULL;
1448
- }
1449
-
1450
- // Rdoc needs to know
1451
- #ifdef RDOC_NEVER_DEFINED
1452
- mLibXML = rb_define_module("LibXML");
1453
- mXML = rb_define_module_under(mLibXML, "XML");
1454
- #endif
1455
-
1456
- void
1457
- ruby_init_xml_node(void) {
1458
- xmlRegisterNodeDefault(ruby_xml_node_registerNode);
1459
- xmlDeregisterNodeDefault(ruby_xml_node_deregisterNode);
1460
-
1461
- cXMLNode = rb_define_class_under(mXML, "Node", rb_cObject);
1462
- eXMLNodeSetNamespace = rb_define_class_under(cXMLNode, "SetNamespace", eXMLError);
1463
- eXMLNodeFailedModify = rb_define_class_under(cXMLNode, "FailedModify", eXMLError);
1464
- eXMLNodeUnknownType = rb_define_class_under(cXMLNode, "UnknownType", eXMLError);
1465
-
1466
- rb_define_const(cXMLNode, "SPACE_DEFAULT", INT2NUM(0));
1467
- rb_define_const(cXMLNode, "SPACE_PRESERVE", INT2NUM(1));
1468
- rb_define_const(cXMLNode, "SPACE_NOT_INHERIT", INT2NUM(-1));
1469
- rb_define_const(cXMLNode, "XLINK_ACTUATE_AUTO", INT2NUM(1));
1470
- rb_define_const(cXMLNode, "XLINK_ACTUATE_NONE", INT2NUM(0));
1471
- rb_define_const(cXMLNode, "XLINK_ACTUATE_ONREQUEST", INT2NUM(2));
1472
- rb_define_const(cXMLNode, "XLINK_SHOW_EMBED", INT2NUM(2));
1473
- rb_define_const(cXMLNode, "XLINK_SHOW_NEW", INT2NUM(1));
1474
- rb_define_const(cXMLNode, "XLINK_SHOW_NONE", INT2NUM(0));
1475
- rb_define_const(cXMLNode, "XLINK_SHOW_REPLACE", INT2NUM(3));
1476
- rb_define_const(cXMLNode, "XLINK_TYPE_EXTENDED", INT2NUM(2));
1477
- rb_define_const(cXMLNode, "XLINK_TYPE_EXTENDED_SET", INT2NUM(3));
1478
- rb_define_const(cXMLNode, "XLINK_TYPE_NONE", INT2NUM(0));
1479
- rb_define_const(cXMLNode, "XLINK_TYPE_SIMPLE", INT2NUM(1));
1480
-
1481
- rb_define_const(cXMLNode, "ELEMENT_NODE", INT2FIX(XML_ELEMENT_NODE));
1482
- rb_define_const(cXMLNode, "ATTRIBUTE_NODE", INT2FIX(XML_ATTRIBUTE_NODE));
1483
- rb_define_const(cXMLNode, "TEXT_NODE", INT2FIX(XML_TEXT_NODE));
1484
- rb_define_const(cXMLNode, "CDATA_SECTION_NODE", INT2FIX(XML_CDATA_SECTION_NODE));
1485
- rb_define_const(cXMLNode, "ENTITY_REF_NODE", INT2FIX(XML_ENTITY_REF_NODE));
1486
- rb_define_const(cXMLNode, "ENTITY_NODE", INT2FIX(XML_ENTITY_NODE));
1487
- rb_define_const(cXMLNode, "PI_NODE", INT2FIX(XML_PI_NODE));
1488
- rb_define_const(cXMLNode, "COMMENT_NODE", INT2FIX(XML_COMMENT_NODE));
1489
- rb_define_const(cXMLNode, "DOCUMENT_NODE", INT2FIX(XML_DOCUMENT_NODE));
1490
- rb_define_const(cXMLNode, "DOCUMENT_TYPE_NODE", INT2FIX(XML_DOCUMENT_TYPE_NODE));
1491
- rb_define_const(cXMLNode, "DOCUMENT_FRAG_NODE", INT2FIX(XML_DOCUMENT_FRAG_NODE));
1492
- rb_define_const(cXMLNode, "NOTATION_NODE", INT2FIX(XML_NOTATION_NODE));
1493
- rb_define_const(cXMLNode, "HTML_DOCUMENT_NODE", INT2FIX(XML_HTML_DOCUMENT_NODE));
1494
- rb_define_const(cXMLNode, "DTD_NODE", INT2FIX(XML_DTD_NODE));
1495
- rb_define_const(cXMLNode, "ELEMENT_DECL", INT2FIX(XML_ELEMENT_DECL));
1496
- rb_define_const(cXMLNode, "ATTRIBUTE_DECL", INT2FIX(XML_ATTRIBUTE_DECL));
1497
- rb_define_const(cXMLNode, "ENTITY_DECL", INT2FIX(XML_ENTITY_DECL));
1498
- rb_define_const(cXMLNode, "NAMESPACE_DECL", INT2FIX(XML_NAMESPACE_DECL));
1499
- rb_define_const(cXMLNode, "XINCLUDE_START", INT2FIX(XML_XINCLUDE_START));
1500
- rb_define_const(cXMLNode, "XINCLUDE_END", INT2FIX(XML_XINCLUDE_END));
1501
-
1502
- #ifdef LIBXML_DOCB_ENABLED
1503
- rb_define_const(cXMLNode, "DOCB_DOCUMENT_NODE", INT2FIX(XML_DOCB_DOCUMENT_NODE));
1504
- #else
1505
- rb_define_const(cXMLNode, "DOCB_DOCUMENT_NODE", Qnil);
1506
- #endif
1507
-
1508
-
1509
- rb_define_singleton_method(cXMLNode, "new2", ruby_xml_node2_new_native, 2);
1510
- rb_define_singleton_method(cXMLNode, "new", ruby_xml_node2_new_string_bc, -1);
1511
- rb_define_singleton_method(cXMLNode, "new_cdata", ruby_xml_node_new_cdata, -1);
1512
- rb_define_singleton_method(cXMLNode, "new_comment", ruby_xml_node_new_comment, -1);
1513
- rb_define_singleton_method(cXMLNode, "new_text", ruby_xml_node_new_text, 1);
1514
-
1515
- /* Traversal */
1516
- rb_include_module(cXMLNode, rb_mEnumerable);
1517
- rb_define_method(cXMLNode, "[]", ruby_xml_node_property_get, 1);
1518
- rb_define_method(cXMLNode, "each", ruby_xml_node_each, 0);
1519
- rb_define_method(cXMLNode, "first", ruby_xml_node_first_get, 0);
1520
- rb_define_method(cXMLNode, "last", ruby_xml_node_last_get, 0);
1521
- rb_define_method(cXMLNode, "next", ruby_xml_node_next_get, 0);
1522
- rb_define_method(cXMLNode, "parent", ruby_xml_node_parent_get, 0);
1523
- rb_define_method(cXMLNode, "prev", ruby_xml_node_prev_get, 0);
1524
-
1525
- /* Modification */
1526
- rb_define_method(cXMLNode, "<<", ruby_xml_node_content_add, 1);
1527
- rb_define_method(cXMLNode, "[]=", ruby_xml_node_property_set, 2);
1528
- rb_define_method(cXMLNode, "child_add", ruby_xml_node_child_add, 1);
1529
- rb_define_method(cXMLNode, "child=", ruby_xml_node_child_set, 1);
1530
- rb_define_method(cXMLNode, "sibling=", ruby_xml_node_sibling_set, 1);
1531
- rb_define_method(cXMLNode, "next=", ruby_xml_node_next_set, 1);
1532
- rb_define_method(cXMLNode, "prev=", ruby_xml_node_prev_set, 1);
1533
-
1534
-
1535
- /* Rest of the node api */
1536
- rb_define_method(cXMLNode, "attributes", ruby_xml_node_attributes_get, 0);
1537
- rb_define_method(cXMLNode, "base", ruby_xml_node_base_get, 0);
1538
- rb_define_method(cXMLNode, "base=", ruby_xml_node_base_set, 1);
1539
- rb_define_method(cXMLNode, "blank?", ruby_xml_node_empty_q, 0);
1540
- rb_define_method(cXMLNode, "copy", ruby_xml_node_copy, 1);
1541
- rb_define_method(cXMLNode, "content", ruby_xml_node_content_get, 0);
1542
- rb_define_method(cXMLNode, "content=", ruby_xml_node_content_set, 1);
1543
- rb_define_method(cXMLNode, "content_stripped", ruby_xml_node_content_stripped_get, 0);
1544
- rb_define_method(cXMLNode, "doc", ruby_xml_node_doc, 0);
1545
- rb_define_method(cXMLNode, "dump", ruby_xml_node_dump, 0);
1546
- rb_define_method(cXMLNode, "debug_dump", ruby_xml_node_debug_dump, 0);
1547
- rb_define_method(cXMLNode, "empty?", ruby_xml_node_empty_q, 0);
1548
- rb_define_method(cXMLNode, "eql?", ruby_xml_node_eql_q, 1);
1549
- rb_define_method(cXMLNode, "lang", ruby_xml_node_lang_get, 0);
1550
- rb_define_method(cXMLNode, "lang=", ruby_xml_node_lang_set, 1);
1551
- rb_define_method(cXMLNode, "line_num", ruby_xml_node_line_num, 0);
1552
- rb_define_method(cXMLNode, "name", ruby_xml_node_name_get, 0);
1553
- rb_define_method(cXMLNode, "name=", ruby_xml_node_name_set, 1);
1554
- rb_define_method(cXMLNode, "namespace", ruby_xml_node_namespace_get, 0);
1555
- rb_define_method(cXMLNode, "namespace_node", ruby_xml_node_namespace_get_node, 0);
1556
- rb_define_method(cXMLNode, "namespace=", ruby_xml_node_namespace_set, -1);
1557
- rb_define_method(cXMLNode, "node_type", ruby_xml_node_type, 0);
1558
- rb_define_method(cXMLNode, "ns", ruby_xml_node_namespace_get, 0);
1559
- rb_define_method(cXMLNode, "ns?", ruby_xml_node_ns_q, 0);
1560
- rb_define_method(cXMLNode, "ns_def?", ruby_xml_node_ns_def_q, 0);
1561
- rb_define_method(cXMLNode, "ns_def", ruby_xml_node_ns_def_get, 0);
1562
- rb_define_method(cXMLNode, "path", ruby_xml_node_path, 0);
1563
- rb_define_method(cXMLNode, "pointer", ruby_xml_node_pointer, 1);
1564
- rb_define_method(cXMLNode, "remove!", ruby_xml_node_remove_ex, 0);
1565
- rb_define_method(cXMLNode, "search_ns", ruby_xml_node_search_ns, 1);
1566
- rb_define_method(cXMLNode, "search_href", ruby_xml_node_search_href, 1);
1567
- rb_define_method(cXMLNode, "space_preserve", ruby_xml_node_space_preserve_get, 0);
1568
- rb_define_method(cXMLNode, "space_preserve=", ruby_xml_node_space_preserve_set, 1);
1569
- rb_define_method(cXMLNode, "to_s", ruby_xml_node_to_s, 0);
1570
- rb_define_method(cXMLNode, "xlink?", ruby_xml_node_xlink_q, 0);
1571
- rb_define_method(cXMLNode, "xlink_type", ruby_xml_node_xlink_type, 0);
1572
- rb_define_method(cXMLNode, "xlink_type_name", ruby_xml_node_xlink_type_name, 0);
1573
-
1574
- rb_define_alias(cXMLNode, "==", "eql?");
1575
-
1576
- /* :nodoc: */
1577
- {
1578
- VALUE singleton;
1579
- singleton = rb_singleton_class(cXMLNode);
1580
- rb_define_alias(singleton, "new_element", "new");
1581
- }
1582
- }
1
+ /* $Id: ruby_xml_node.c 560 2008-11-18 04:09:19Z 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
+
10
+ /* Document-class: LibXML::XML::Node
11
+ *
12
+ * Nodes are the primary objects that make up an XML document.
13
+ * The node class represents most node types that are found in
14
+ * an XML document (but not Attributes, see LibXML::XML::Attribute).
15
+ * It exposes libxml's full API for creating, querying
16
+ * moving and deleting node objects. Many of these methods are
17
+ * documented in the DOM Level 3 specification found at:
18
+ * http://www.w3.org/TR/DOM-Level-3-Core/. */
19
+
20
+
21
+ VALUE
22
+ check_string_or_symbol( VALUE val ) {
23
+ if( TYPE(val) != T_STRING && TYPE(val) != T_SYMBOL ) {
24
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected String or Symbol)",
25
+ rb_obj_classname(val) );
26
+ }
27
+ return rb_obj_as_string( val );
28
+ }
29
+
30
+
31
+ /*
32
+ * call-seq:
33
+ * node.base -> "uri"
34
+ *
35
+ * Obtain this node's base URI.
36
+ */
37
+ VALUE
38
+ ruby_xml_node_base_get(VALUE self) {
39
+ xmlNodePtr xnode;
40
+ xmlChar* base_uri;
41
+ VALUE result = Qnil;
42
+
43
+ Data_Get_Struct(self, xmlNode, xnode);
44
+
45
+ if (xnode->doc == NULL)
46
+ return(result);
47
+
48
+ base_uri = xmlNodeGetBase(xnode->doc, xnode);
49
+ if (base_uri) {
50
+ result = rb_str_new2((const char*)base_uri);
51
+ xmlFree(base_uri);
52
+ }
53
+
54
+ return(result);
55
+ }
56
+
57
+
58
+ // TODO node_base_set should support setting back to nil
59
+
60
+ /*
61
+ * call-seq:
62
+ * node.base = "uri"
63
+ *
64
+ * Set this node's base URI.
65
+ */
66
+ VALUE
67
+ ruby_xml_node_base_set(VALUE self, VALUE uri) {
68
+ xmlNodePtr xnode;
69
+
70
+ Check_Type(uri, T_STRING);
71
+ Data_Get_Struct(self, xmlNode, xnode);
72
+ if (xnode->doc == NULL)
73
+ return(Qnil);
74
+
75
+ xmlNodeSetBase(xnode, (xmlChar*)StringValuePtr(uri));
76
+ return(Qtrue);
77
+ }
78
+
79
+
80
+ /*
81
+ * call-seq:
82
+ * node.content -> "string"
83
+ *
84
+ * Obtain this node's content as a string.
85
+ */
86
+ VALUE
87
+ ruby_xml_node_content_get(VALUE self) {
88
+ xmlNodePtr xnode;
89
+ xmlChar *content;
90
+ VALUE result = Qnil;
91
+
92
+ Data_Get_Struct(self, xmlNode, xnode);
93
+ content = xmlNodeGetContent(xnode);
94
+ if (content) {
95
+ result = rb_str_new2((const char *) content);
96
+ xmlFree(content);
97
+ }
98
+
99
+ return result;
100
+ }
101
+
102
+ /*
103
+ * call-seq:
104
+ * node.content = "string"
105
+ *
106
+ * Set this node's content to the specified string.
107
+ */
108
+ VALUE
109
+ ruby_xml_node_content_set(VALUE self, VALUE content) {
110
+ xmlNodePtr xnode;
111
+
112
+ Check_Type(content, T_STRING);
113
+ Data_Get_Struct(self, xmlNode, xnode);
114
+ // XXX docs indicate need for escaping entites, need to be done? danj
115
+ xmlNodeSetContent(xnode, (xmlChar*)StringValuePtr(content));
116
+ return(Qtrue);
117
+ }
118
+
119
+
120
+ /*
121
+ * call-seq:
122
+ * node.content_stripped -> "string"
123
+ *
124
+ * Obtain this node's stripped content.
125
+ *
126
+ * *Deprecated*: Stripped content can be obtained via the
127
+ * +content+ method.
128
+ */
129
+ VALUE
130
+ ruby_xml_node_content_stripped_get(VALUE self) {
131
+ xmlNodePtr xnode;
132
+ xmlChar* content;
133
+ VALUE result = Qnil;
134
+
135
+ Data_Get_Struct(self, xmlNode, xnode);
136
+
137
+ if (!xnode->content)
138
+ return result;
139
+
140
+ content = xmlNodeGetContent(xnode);
141
+ if (content) {
142
+ result = rb_str_new2((const char*)content);
143
+ xmlFree(content);
144
+ }
145
+ return(result);
146
+ }
147
+
148
+ /*
149
+ * call-seq:
150
+ * node.first -> XML::Node
151
+ *
152
+ * Returns this node's first child node if any.
153
+ */
154
+ VALUE
155
+ ruby_xml_node_first_get(VALUE self) {
156
+ xmlNodePtr xnode;
157
+
158
+ Data_Get_Struct(self, xmlNode, xnode);
159
+
160
+ if (xnode->children)
161
+ return(ruby_xml_node2_wrap(cXMLNode, xnode->children));
162
+ else
163
+ return(Qnil);
164
+ }
165
+
166
+
167
+ /*
168
+ * underlying for child_set and child_add, difference being
169
+ * former raises on implicit copy, latter does not.
170
+ */
171
+ VALUE
172
+ ruby_xml_node_child_set_aux(VALUE self, VALUE rnode) {
173
+ xmlNodePtr pnode, chld, ret;
174
+
175
+ if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
176
+ rb_raise(rb_eTypeError, "Must pass an XML::Node object");
177
+
178
+ Data_Get_Struct(self, xmlNode, pnode);
179
+ Data_Get_Struct(rnode, xmlNode, chld);
180
+
181
+ if ( chld->parent != NULL || chld->doc != NULL )
182
+ rb_raise(rb_eRuntimeError, "Cannot move a node from one document to another with child= or <<. First copy the node before moving it.");
183
+
184
+ ret = xmlAddChild(pnode, chld);
185
+ if (ret == NULL) {
186
+ ruby_xml_raise(&xmlLastError);
187
+ } else if ( ret==chld ) {
188
+ /* child was added whole to parent and we need to return it as a new object */
189
+ return ruby_xml_node2_wrap(cXMLNode,chld);
190
+ }
191
+ /* else */
192
+ /* If it was a text node, then ret should be parent->last, so we will just return ret. */
193
+ return ruby_xml_node2_wrap(cXMLNode,ret);
194
+ }
195
+
196
+ /*
197
+ * call-seq:
198
+ * node.child = node
199
+ *
200
+ * Set a child node for this node. Also called for <<
201
+ */
202
+ VALUE
203
+ ruby_xml_node_child_set(VALUE self, VALUE rnode) {
204
+ return ruby_xml_node_child_set_aux(self, rnode);
205
+ }
206
+
207
+
208
+ /*
209
+ * call-seq:
210
+ * node << ("string" | node) -> XML::Node
211
+ *
212
+ * Add the specified string or XML::Node to this node's
213
+ * content. The returned node is the node that was
214
+ * added and not self, thereby allowing << calls to
215
+ * be chained.
216
+ */
217
+ VALUE
218
+ ruby_xml_node_content_add(VALUE self, VALUE obj) {
219
+ xmlNodePtr xnode;
220
+ VALUE str;
221
+
222
+ Data_Get_Struct(self, xmlNode, xnode);
223
+ /* XXX This should only be legal for a CDATA type node, I think,
224
+ * resulting in a merge of content, as if a string were passed
225
+ * danj 070827
226
+ */
227
+ if (rb_obj_is_kind_of(obj, cXMLNode)) {
228
+ ruby_xml_node_child_set(self, obj);
229
+ } else {
230
+ str = rb_obj_as_string(obj);
231
+ if (NIL_P(str) || TYPE(str) != T_STRING)
232
+ rb_raise(rb_eTypeError, "invalid argument: must be string or XML::Node");
233
+
234
+ xmlNodeAddContent(xnode, (xmlChar*)StringValuePtr(str));
235
+ }
236
+ return(self);
237
+ }
238
+
239
+ /*
240
+ * call-seq:
241
+ * node.child_add(node)
242
+ *
243
+ * Set a child node for this node.
244
+ */
245
+ VALUE
246
+ ruby_xml_node_child_add(VALUE self, VALUE rnode) {
247
+ return ruby_xml_node_child_set_aux(self, rnode);
248
+ }
249
+
250
+ /*
251
+ * call-seq:
252
+ * node.doc -> document
253
+ *
254
+ * Obtain the XML::Document this node belongs to.
255
+ */
256
+ VALUE
257
+ ruby_xml_node_doc(VALUE self) {
258
+ xmlNodePtr xnode;
259
+ xmlDocPtr doc=NULL;
260
+
261
+ Data_Get_Struct(self, xmlNode, xnode);
262
+
263
+ switch (xnode->type) {
264
+ case XML_DOCUMENT_NODE:
265
+ #ifdef LIBXML_DOCB_ENABLED
266
+ case XML_DOCB_DOCUMENT_NODE:
267
+ #endif
268
+ case XML_HTML_DOCUMENT_NODE:
269
+ doc = NULL;
270
+ break;
271
+ case XML_ATTRIBUTE_NODE:
272
+ {
273
+ xmlAttrPtr attr = (xmlAttrPtr) xnode;
274
+ doc = attr->doc;
275
+ break;
276
+ }
277
+ case XML_NAMESPACE_DECL:
278
+ doc = NULL;
279
+ break;
280
+ default:
281
+ doc = xnode->doc;
282
+ break;
283
+ }
284
+
285
+ if (doc == NULL)
286
+ return(Qnil);
287
+
288
+ if ( doc->_private == NULL )
289
+ rb_raise(rb_eRuntimeError,"existing document object has no ruby-instance");
290
+
291
+ return (VALUE)doc->_private;
292
+ }
293
+
294
+
295
+ /*
296
+ * call-seq:
297
+ * node.dump -> (true|nil)
298
+ *
299
+ * Dump this node to stdout.
300
+ */
301
+ VALUE
302
+ ruby_xml_node_dump(VALUE self) {
303
+ xmlNodePtr xnode;
304
+ xmlBufferPtr buf;
305
+
306
+ Data_Get_Struct(self, xmlNode, xnode);
307
+
308
+ if (xnode->doc == NULL)
309
+ return(Qnil);
310
+
311
+ buf = xmlBufferCreate();
312
+ xmlNodeDump(buf, xnode->doc, xnode, 0, 1);
313
+ xmlBufferDump(stdout, buf);
314
+ xmlBufferFree(buf);
315
+ return(Qtrue);
316
+ }
317
+
318
+
319
+ /*
320
+ * call-seq:
321
+ * node.debug_dump -> (true|nil)
322
+ *
323
+ * Dump this node to stdout, including any debugging
324
+ * information.
325
+ */
326
+ VALUE
327
+ ruby_xml_node_debug_dump(VALUE self) {
328
+ xmlNodePtr xnode;
329
+ Data_Get_Struct(self, xmlNode, xnode);
330
+
331
+ if (xnode->doc == NULL)
332
+ return(Qnil);
333
+
334
+ xmlElemDump(stdout, xnode->doc, xnode);
335
+ return(Qtrue);
336
+ }
337
+
338
+ /*
339
+ * call-seq:
340
+ * node.each -> XML::Node
341
+ *
342
+ * Iterates over this node's children, including text
343
+ * nodes, element nodes, etc. If you wish to iterate
344
+ * only over child elements, use XML::Node#each_element.
345
+ *
346
+ * doc = XML::Document.new('model/books.xml')
347
+ * doc.root.each {|node| puts node}
348
+ */
349
+ VALUE
350
+ ruby_xml_node_each(VALUE self) {
351
+ xmlNodePtr xnode;
352
+ xmlNodePtr xchild;
353
+ Data_Get_Struct(self, xmlNode, xnode);
354
+
355
+ xchild = xnode->children;
356
+
357
+ while (xchild) {
358
+ rb_yield(ruby_xml_node2_wrap(cXMLNode, xchild));
359
+ xchild = xchild->next;
360
+ }
361
+ return Qnil;
362
+ }
363
+
364
+
365
+ /*
366
+ * call-seq:
367
+ * node.empty? -> (true|false)
368
+ *
369
+ * Determine whether this node is empty.
370
+ */
371
+ VALUE
372
+ ruby_xml_node_empty_q(VALUE self) {
373
+ xmlNodePtr xnode;
374
+ Data_Get_Struct(self, xmlNode, xnode);
375
+ if (xnode == NULL)
376
+ return(Qnil);
377
+
378
+ return((xmlIsBlankNode(xnode) == 1) ? Qtrue : Qfalse);
379
+ }
380
+
381
+
382
+ VALUE ruby_xml_node_to_s(VALUE self);
383
+
384
+ /*
385
+ * call-seq:
386
+ * node.eql?(other_node) => (true|false)
387
+ *
388
+ * Test equality between the two nodes. Two nodes are equal
389
+ * if they are the same node or have the same XML representation.*/
390
+ VALUE
391
+ ruby_xml_node_eql_q(VALUE self, VALUE other) {
392
+ if (self == other)
393
+ {
394
+ return Qtrue;
395
+ }
396
+ else if NIL_P(other)
397
+ {
398
+ return Qfalse;
399
+ }
400
+ else
401
+ {
402
+ VALUE self_xml;
403
+ VALUE other_xml;
404
+
405
+ if (rb_obj_is_kind_of(other, cXMLNode) == Qfalse)
406
+ rb_raise(rb_eTypeError, "Nodes can only be compared against other nodes");
407
+
408
+ self_xml = ruby_xml_node_to_s(self);
409
+ other_xml = ruby_xml_node_to_s(other);
410
+ return(rb_funcall(self_xml, rb_intern("=="), 1, other_xml));
411
+ }
412
+ }
413
+
414
+ /*
415
+ * call-seq:
416
+ * XML::Node.new_cdata(content = nil) -> XML::Node
417
+ *
418
+ * Create a new #CDATA node, optionally setting
419
+ * the node's content.
420
+ */
421
+ VALUE
422
+ ruby_xml_node_new_cdata(int argc, VALUE *argv, VALUE class) {
423
+ xmlNodePtr xnode;
424
+ VALUE str=Qnil;
425
+
426
+ switch(argc) {
427
+ case 1:
428
+ str = argv[0];
429
+ Check_Type(str, T_STRING);
430
+ if (!NIL_P(str)) {
431
+ xnode = xmlNewCDataBlock(NULL, (xmlChar*)StringValuePtr(str), xmlStrlen((xmlChar*)StringValuePtr(str)));
432
+ } else {
433
+ xnode = xmlNewCDataBlock(NULL, NULL , 0);
434
+ }
435
+
436
+ if (xnode == NULL)
437
+ return(Qnil);
438
+
439
+ return ruby_xml_node2_wrap(class,xnode);
440
+
441
+ default:
442
+ rb_raise(rb_eArgError, "wrong number of arguments (1)");
443
+ }
444
+
445
+ // not reached
446
+ return(Qnil);
447
+ }
448
+
449
+
450
+ /*
451
+ * call-seq:
452
+ * XML::Node.new_comment(content = nil) -> XML::Node
453
+ *
454
+ * Create a new comment node, optionally setting
455
+ * the node's content.
456
+ *
457
+ */
458
+ VALUE
459
+ ruby_xml_node_new_comment(int argc, VALUE *argv, VALUE class) {
460
+ xmlNodePtr xnode;
461
+ VALUE str=Qnil;
462
+
463
+ switch(argc) {
464
+ case 1:
465
+ str = argv[0];
466
+ Check_Type(str, T_STRING);
467
+ // TODO xmlNewComment wrongly? adds \n before and after the comment
468
+ if (!NIL_P(str)) {
469
+ xnode = xmlNewComment((xmlChar*)StringValuePtr(str));
470
+ } else {
471
+ xnode = xmlNewComment(NULL);
472
+ }
473
+
474
+ if (xnode == NULL)
475
+ return(Qnil);
476
+
477
+ return ruby_xml_node2_wrap(class,xnode);
478
+
479
+ default:
480
+ rb_raise(rb_eArgError, "wrong number of arguments (1)");
481
+ }
482
+
483
+ // not reached
484
+ return(Qnil);
485
+ }
486
+
487
+
488
+ /*
489
+ * call-seq:
490
+ * node.lang -> "string"
491
+ *
492
+ * Obtain the language set for this node, if any.
493
+ * This is set in XML via the xml:lang attribute.
494
+ */
495
+ VALUE
496
+ ruby_xml_node_lang_get(VALUE self) {
497
+ xmlNodePtr xnode;
498
+ xmlChar *lang;
499
+ VALUE result = Qnil;
500
+
501
+ Data_Get_Struct(self, xmlNode, xnode);
502
+ lang = xmlNodeGetLang(xnode);
503
+
504
+ if (lang) {
505
+ result = rb_str_new2((const char*)lang);
506
+ xmlFree(lang);
507
+ }
508
+
509
+ return(result);
510
+ }
511
+
512
+
513
+ // TODO node_lang_set should support setting back to nil
514
+
515
+ /*
516
+ * call-seq:
517
+ * node.lang = "string"
518
+ *
519
+ * Set the language for this node. This affects the value
520
+ * of the xml:lang attribute.
521
+ */
522
+ VALUE
523
+ ruby_xml_node_lang_set(VALUE self, VALUE lang) {
524
+ xmlNodePtr xnode;
525
+
526
+ Check_Type(lang, T_STRING);
527
+ Data_Get_Struct(self, xmlNode, xnode);
528
+ xmlNodeSetLang(xnode, (xmlChar*)StringValuePtr(lang));
529
+
530
+ return(Qtrue);
531
+ }
532
+
533
+
534
+ /*
535
+ * call-seq:
536
+ * node.last -> XML::Node
537
+ *
538
+ * Obtain the last child node of this node, if any.
539
+ */
540
+ VALUE
541
+ ruby_xml_node_last_get(VALUE self) {
542
+ xmlNodePtr xnode;
543
+
544
+ Data_Get_Struct(self, xmlNode, xnode);
545
+
546
+ if (xnode->last)
547
+ return(ruby_xml_node2_wrap(cXMLNode, xnode->last));
548
+ else
549
+ return(Qnil);
550
+ }
551
+
552
+ /*
553
+ * call-seq:
554
+ * node.line_num -> num
555
+ *
556
+ * Obtain the line number (in the XML document) that this
557
+ * node was read from. If +default_line_numbers+ is set
558
+ * false (the default), this method returns zero.
559
+ */
560
+ VALUE
561
+ ruby_xml_node_line_num(VALUE self) {
562
+ xmlNodePtr xnode;
563
+ long line_num;
564
+ Data_Get_Struct(self, xmlNode, xnode);
565
+
566
+ if (!xmlLineNumbersDefaultValue)
567
+ rb_warn("Line numbers were not retained: use XML::Parser::default_line_numbers=true");
568
+
569
+ line_num = xmlGetLineNo(xnode);
570
+ if (line_num == -1)
571
+ return(Qnil);
572
+ else
573
+ return(INT2NUM((long)line_num));
574
+ }
575
+
576
+
577
+ /*
578
+ * call-seq:
579
+ * node.xlink? -> (true|false)
580
+ *
581
+ * Determine whether this node is an xlink node.
582
+ */
583
+ VALUE
584
+ ruby_xml_node_xlink_q(VALUE self) {
585
+ xmlNodePtr xnode;
586
+ xlinkType xlt;
587
+
588
+ Data_Get_Struct(self, xmlNode, xnode);
589
+ xlt = xlinkIsLink(xnode->doc, xnode);
590
+
591
+ if (xlt == XLINK_TYPE_NONE)
592
+ return(Qfalse);
593
+ else
594
+ return(Qtrue);
595
+ }
596
+
597
+
598
+ /*
599
+ * call-seq:
600
+ * node.xlink_type -> num
601
+ *
602
+ * Obtain the type identifier for this xlink, if applicable.
603
+ * If this is not an xlink node (see +xlink?+), will return
604
+ * nil.
605
+ */
606
+ VALUE
607
+ ruby_xml_node_xlink_type(VALUE self) {
608
+ xmlNodePtr xnode;
609
+ xlinkType xlt;
610
+
611
+ Data_Get_Struct(self, xmlNode, xnode);
612
+ xlt = xlinkIsLink(xnode->doc, xnode);
613
+
614
+ if (xlt == XLINK_TYPE_NONE)
615
+ return(Qnil);
616
+ else
617
+ return(INT2NUM(xlt));
618
+ }
619
+
620
+
621
+ /*
622
+ * call-seq:
623
+ * node.xlink_type_name -> "string"
624
+ *
625
+ * Obtain the type name for this xlink, if applicable.
626
+ * If this is not an xlink node (see +xlink?+), will return
627
+ * nil.
628
+ */
629
+ VALUE
630
+ ruby_xml_node_xlink_type_name(VALUE self) {
631
+ xmlNodePtr xnode;
632
+ xlinkType xlt;
633
+
634
+ Data_Get_Struct(self, xmlNode, xnode);
635
+ xlt = xlinkIsLink(xnode->doc, xnode);
636
+
637
+ switch(xlt) {
638
+ case XLINK_TYPE_NONE:
639
+ return(Qnil);
640
+ case XLINK_TYPE_SIMPLE:
641
+ return(rb_str_new2("simple"));
642
+ case XLINK_TYPE_EXTENDED:
643
+ return(rb_str_new2("extended"));
644
+ case XLINK_TYPE_EXTENDED_SET:
645
+ return(rb_str_new2("extended_set"));
646
+ default:
647
+ rb_fatal("Unknowng xlink type, %d", xlt);
648
+ }
649
+ }
650
+
651
+ /*
652
+ * call-seq:
653
+ * node.name -> "string"
654
+ *
655
+ * Obtain this node's name.
656
+ */
657
+ VALUE
658
+ ruby_xml_node_name_get(VALUE self) {
659
+ xmlNodePtr xnode;
660
+ const xmlChar *name;
661
+
662
+ Data_Get_Struct(self, xmlNode, xnode);
663
+
664
+ switch (xnode->type) {
665
+ case XML_DOCUMENT_NODE:
666
+ #ifdef LIBXML_DOCB_ENABLED
667
+ case XML_DOCB_DOCUMENT_NODE:
668
+ #endif
669
+ case XML_HTML_DOCUMENT_NODE:
670
+ {
671
+ xmlDocPtr doc = (xmlDocPtr) xnode;
672
+ name = doc->URL;
673
+ break;
674
+ }
675
+ case XML_ATTRIBUTE_NODE:
676
+ {
677
+ xmlAttrPtr attr = (xmlAttrPtr) xnode;
678
+ name = attr->name;
679
+ break;
680
+ }
681
+ case XML_NAMESPACE_DECL:
682
+ {
683
+ xmlNsPtr ns = (xmlNsPtr) xnode;
684
+ name = ns->prefix;
685
+ break;
686
+ }
687
+ default:
688
+ name = xnode->name;
689
+ break;
690
+ }
691
+
692
+ if (xnode->name == NULL)
693
+ return(Qnil);
694
+ else
695
+ return(rb_str_new2((const char*)name));
696
+ }
697
+
698
+
699
+ /*
700
+ * call-seq:
701
+ * node.name = "string"
702
+ *
703
+ * Set this node's name.
704
+ */
705
+ VALUE
706
+ ruby_xml_node_name_set(VALUE self, VALUE name) {
707
+ xmlNodePtr xnode;
708
+
709
+ Check_Type(name, T_STRING);
710
+ Data_Get_Struct(self, xmlNode, xnode);
711
+ xmlNodeSetName(xnode, (xmlChar*)StringValuePtr(name));
712
+ return(Qtrue);
713
+ }
714
+
715
+
716
+ /*
717
+ * call-seq:
718
+ * node.namespace -> [namespace, ..., namespace]
719
+ *
720
+ * Obtain an array of +XML::NS+ objects representing
721
+ * this node's xmlns attributes
722
+ */
723
+ VALUE
724
+ ruby_xml_node_namespace_get(VALUE self) {
725
+ xmlNodePtr xnode;
726
+ xmlNsPtr *nsList, *cur;
727
+ VALUE arr, ns;
728
+
729
+ Data_Get_Struct(self, xmlNode, xnode);
730
+ if (xnode == NULL)
731
+ return(Qnil);
732
+
733
+ nsList = xmlGetNsList(xnode->doc, xnode);
734
+
735
+ if (nsList == NULL)
736
+ return(Qnil);
737
+
738
+ arr = rb_ary_new();
739
+ for (cur = nsList; *cur != NULL; cur++) {
740
+ ns = ruby_xml_ns_wrap(*cur);
741
+ if (ns == Qnil)
742
+ continue;
743
+ else
744
+ rb_ary_push(arr, ns);
745
+ }
746
+ xmlFree(nsList);
747
+
748
+ return(arr);
749
+ }
750
+
751
+
752
+ /*
753
+ * call-seq:
754
+ * node.namespace_node -> namespace.
755
+ *
756
+ * Obtain this node's namespace node.
757
+ */
758
+ VALUE
759
+ ruby_xml_node_namespace_get_node(VALUE self) {
760
+ xmlNodePtr xnode;
761
+
762
+ Data_Get_Struct(self, xmlNode, xnode);
763
+ if (xnode->ns == NULL)
764
+ return(Qnil);
765
+ else
766
+ return ruby_xml_ns_wrap(xnode->ns);
767
+ }
768
+
769
+ // TODO namespace_set can take varargs (in fact, must if used
770
+ // with strings), but I cannot see how you can call
771
+ // that version, apart from with 'send'
772
+ //
773
+ // Would sure be nice to support foo.namespace['foo'] = 'bar'
774
+ // but maybe that's not practical...
775
+
776
+ /*
777
+ * call-seq:
778
+ * node.namespace = namespace
779
+ *
780
+ * Add the specified XML::NS object to this node's xmlns attributes.
781
+ */
782
+ VALUE
783
+ ruby_xml_node_namespace_set(int argc, VALUE *argv, VALUE self) {
784
+ VALUE rns, rprefix;
785
+ xmlNodePtr xnode;
786
+ xmlNsPtr xns;
787
+ char *cp, *href;
788
+
789
+ Data_Get_Struct(self, xmlNode, xnode);
790
+ switch (argc) {
791
+ case 1:
792
+ rns = argv[0];
793
+ if (TYPE(rns) == T_STRING) {
794
+ cp = strchr(StringValuePtr(rns), (int)':');
795
+ if (cp == NULL) {
796
+ rprefix = rns;
797
+ href = NULL;
798
+ } else {
799
+ rprefix = rb_str_new(StringValuePtr(rns), (int)((long)cp - (long)StringValuePtr(rns)));
800
+ href = &cp[1]; /* skip the : */
801
+ }
802
+ } else if (rb_obj_is_kind_of(rns, cXMLNS) == Qtrue) {
803
+ Data_Get_Struct(self, xmlNs, xns);
804
+ xmlSetNs(xnode, xns);
805
+ return(rns);
806
+ } else
807
+ rb_raise(rb_eTypeError, "must pass a string or an XML::Ns object");
808
+
809
+ /* Fall through to next case because when argc == 1, we need to
810
+ * manually setup the additional args unless the arg passed is of
811
+ * cXMLNS type */
812
+ case 2:
813
+ /* Don't want this code run in the fall through case */
814
+ if (argc == 2) {
815
+ rprefix = argv[0];
816
+ href = StringValuePtr(argv[1]);
817
+ }
818
+
819
+ xns = xmlNewNs(xnode, (xmlChar*)href, (xmlChar*)StringValuePtr(rprefix));
820
+ if (xns == NULL)
821
+ ruby_xml_raise(&xmlLastError);
822
+ else
823
+ return ruby_xml_ns_wrap(xns);
824
+ break;
825
+
826
+ default:
827
+ rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
828
+ }
829
+
830
+ /* can't get here */
831
+ return(Qnil);
832
+ }
833
+
834
+
835
+ /*
836
+ * memory2 implementation: xmlNode->_private holds a reference
837
+ * to the wrapping ruby object VALUE when there is one.
838
+ * traversal for marking is upward, and top levels are marked
839
+ * through and lower level mark entry.
840
+ *
841
+ * All ruby retrieval for an xml
842
+ * node will result in the same ruby instance. When all handles to them
843
+ * go out of scope, then ruby_xfree gets called and _private is set to NULL.
844
+ * If the xmlNode has no parent or document, then call xmlFree.
845
+ */
846
+ void
847
+ ruby_xml_node2_free(xmlNodePtr xnode) {
848
+
849
+ if (xnode != NULL) {
850
+ xnode->_private=NULL;
851
+
852
+ if (xnode->doc==NULL && xnode->parent==NULL) {
853
+ xmlFreeNode(xnode);
854
+ }
855
+ }
856
+ }
857
+
858
+ void
859
+ ruby_xml_node_mark_common(xmlNodePtr xnode) {
860
+ if (xnode->parent == NULL ) {
861
+ #ifdef NODE_DEBUG
862
+ fprintf(stderr,"mark no parent r=0x%x *n=0x%x\n",rxn,node);
863
+ #endif
864
+ } else if (xnode->doc != NULL ) {
865
+ if (xnode->doc->_private == NULL) {
866
+ rb_bug("XmlNode Doc is not bound! (%s:%d)",
867
+ __FILE__,__LINE__);
868
+ }
869
+ rb_gc_mark((VALUE)xnode->doc->_private);
870
+ } else {
871
+ while (xnode->parent != NULL )
872
+ xnode = xnode->parent;
873
+ if (xnode->_private == NULL )
874
+ rb_warning("XmlNode Root Parent is not bound! (%s:%d)",
875
+ __FILE__,__LINE__);
876
+ else {
877
+ rb_gc_mark((VALUE)xnode->_private);
878
+ }
879
+ }
880
+ }
881
+
882
+ void
883
+ ruby_xml_node2_mark(xmlNodePtr xnode) {
884
+ if (xnode == NULL ) return;
885
+
886
+ if (xnode->_private == NULL ) {
887
+ rb_warning("XmlNode is not bound! (%s:%d)",
888
+ __FILE__,__LINE__);
889
+ return;
890
+ }
891
+
892
+ ruby_xml_node_mark_common(xnode);
893
+ }
894
+
895
+ VALUE
896
+ ruby_xml_node2_wrap(VALUE class, xmlNodePtr xnode)
897
+ {
898
+ VALUE obj;
899
+
900
+ // This node is already wrapped
901
+ if (xnode->_private != NULL) {
902
+ return (VALUE)xnode->_private;
903
+ }
904
+
905
+ obj=Data_Wrap_Struct(class,
906
+ ruby_xml_node2_mark, ruby_xml_node2_free,
907
+ xnode);
908
+
909
+ xnode->_private=(void*)obj;
910
+ return obj;
911
+ }
912
+
913
+ /*
914
+ * call-seq:
915
+ * XML::Node.new_string(namespace, name, content) -> XML::Node
916
+ *
917
+ * Create a new element node in the specified namespace with the
918
+ * supplied name and content.
919
+ */
920
+ VALUE
921
+ ruby_xml_node_new_string(VALUE klass, VALUE ns, VALUE name, VALUE val)
922
+ {
923
+ xmlNodePtr xnode;
924
+ xmlNsPtr xns = NULL;
925
+ VALUE node;
926
+
927
+ if (!NIL_P(ns)) {
928
+ Data_Get_Struct(ns, xmlNs, xns);
929
+ }
930
+
931
+ xnode = xmlNewNode(xns,(xmlChar*)StringValuePtr(name));
932
+ xnode->_private=NULL;
933
+
934
+ node = ruby_xml_node2_wrap(klass, xnode);
935
+ rb_obj_call_init(node, 0, NULL);
936
+
937
+ if (!NIL_P(val))
938
+ {
939
+ if (TYPE(val) != T_STRING)
940
+ val = rb_obj_as_string(val);
941
+
942
+ ruby_xml_node_content_set(node, val);
943
+ }
944
+ return node;
945
+ }
946
+
947
+ /*
948
+ * call-seq:
949
+ * XML::Node.new(name, content = nil) -> XML::Node
950
+ * XML::Node.new_element(name, content = nil) -> XML::Node
951
+ *
952
+ * Create a new element node with the specified name, optionally setting
953
+ * the node's content.
954
+ * backward compatibility for <.5 new
955
+ */
956
+ VALUE
957
+ ruby_xml_node_new_string_bc(int argc, VALUE *argv, VALUE class)
958
+ {
959
+ VALUE content=Qnil;
960
+ VALUE name=Qnil;
961
+ switch(argc) {
962
+ case 2:
963
+ content=argv[1];
964
+ if ( TYPE(content) != T_STRING)
965
+ content=rb_obj_as_string(content);
966
+
967
+ case 1:
968
+ name=check_string_or_symbol( argv[0] );
969
+ return ruby_xml_node_new_string(class,Qnil,name,content);
970
+
971
+ default:
972
+ rb_raise(rb_eArgError, "wrong number of arguments (1 or 2) given %d",argc);
973
+ }
974
+ }
975
+
976
+ /*
977
+ * call-seq:
978
+ * node.next -> XML::Node
979
+ *
980
+ * Obtain the next sibling node, if any.
981
+ */
982
+ VALUE
983
+ ruby_xml_node_next_get(VALUE self) {
984
+ xmlNodePtr xnode;
985
+
986
+ Data_Get_Struct(self, xmlNode, xnode);
987
+
988
+ if (xnode->next)
989
+ return(ruby_xml_node2_wrap(cXMLNode, xnode->next));
990
+ else
991
+ return(Qnil);
992
+ }
993
+
994
+
995
+ /*
996
+ * call-seq:
997
+ * node.next = node
998
+ *
999
+ * Insert the specified node as this node's next sibling.
1000
+ */
1001
+ VALUE
1002
+ ruby_xml_node_next_set(VALUE self, VALUE rnode) {
1003
+ xmlNodePtr cnode, pnode, ret;
1004
+
1005
+ if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
1006
+ rb_raise(rb_eTypeError, "Must pass an XML::Node object");
1007
+
1008
+ Data_Get_Struct(self, xmlNode, pnode);
1009
+ Data_Get_Struct(rnode, xmlNode, cnode);
1010
+
1011
+ ret = xmlAddNextSibling(pnode, cnode);
1012
+ if (ret == NULL)
1013
+ ruby_xml_raise(&xmlLastError);
1014
+
1015
+ return(ruby_xml_node2_wrap(cXMLNode, ret));
1016
+ }
1017
+
1018
+
1019
+ /*
1020
+ * call-seq:
1021
+ * node.ns? -> (true|false)
1022
+ *
1023
+ * Determine whether this node has a namespace.
1024
+ */
1025
+ VALUE
1026
+ ruby_xml_node_ns_q(VALUE self) {
1027
+ xmlNodePtr xnode;
1028
+ Data_Get_Struct(self, xmlNode, xnode);
1029
+ if (xnode->ns == NULL)
1030
+ return(Qfalse);
1031
+ else
1032
+ return(Qtrue);
1033
+ }
1034
+
1035
+ /*
1036
+ * call-seq:
1037
+ * node.ns_def? -> (true|false)
1038
+ *
1039
+ * Obtain an array of +XML::NS+ objects representing
1040
+ * this node's xmlns attributes
1041
+ */
1042
+ VALUE
1043
+ ruby_xml_node_ns_def_q(VALUE self) {
1044
+ xmlNodePtr xnode;
1045
+ Data_Get_Struct(self, xmlNode, xnode);
1046
+ if (xnode->nsDef == NULL)
1047
+ return(Qfalse);
1048
+ else
1049
+ return(Qtrue);
1050
+ }
1051
+
1052
+
1053
+ /*
1054
+ * call-seq:
1055
+ * node.ns_def -> namespace
1056
+ *
1057
+ * Obtain this node's default namespace.
1058
+ */
1059
+ VALUE
1060
+ ruby_xml_node_ns_def_get(VALUE self) {
1061
+ xmlNodePtr xnode;
1062
+ Data_Get_Struct(self, xmlNode, xnode);
1063
+ if (xnode->nsDef == NULL)
1064
+ return(Qnil);
1065
+ else
1066
+ return(ruby_xml_ns_wrap(xnode->nsDef));
1067
+ }
1068
+
1069
+
1070
+ /*
1071
+ * call-seq:
1072
+ * node.parent -> XML::Node
1073
+ *
1074
+ * Obtain this node's parent node, if any.
1075
+ */
1076
+ VALUE
1077
+ ruby_xml_node_parent_get(VALUE self) {
1078
+ xmlNodePtr xnode;
1079
+
1080
+ Data_Get_Struct(self, xmlNode, xnode);
1081
+
1082
+ if (xnode->parent)
1083
+ return(ruby_xml_node2_wrap(cXMLNode, xnode->parent));
1084
+ else
1085
+ return(Qnil);
1086
+ }
1087
+
1088
+
1089
+ /*
1090
+ * call-seq:
1091
+ * node.path -> path
1092
+ *
1093
+ * Obtain this node's path.
1094
+ */
1095
+ VALUE
1096
+ ruby_xml_node_path(VALUE self) {
1097
+ xmlNodePtr xnode;
1098
+ xmlChar *path;
1099
+
1100
+ Data_Get_Struct(self, xmlNode, xnode);
1101
+ path = xmlGetNodePath(xnode);
1102
+
1103
+ if (path == NULL)
1104
+ return(Qnil);
1105
+ else
1106
+ return(rb_str_new2((const char*)path));
1107
+ }
1108
+
1109
+
1110
+ /*
1111
+ * call-seq:
1112
+ * node.pointer -> XML::NodeSet
1113
+ *
1114
+ * Evaluates an XPointer expression relative to this node.
1115
+ */
1116
+ VALUE
1117
+ ruby_xml_node_pointer(VALUE self, VALUE xptr_str) {
1118
+ return(ruby_xml_xpointer_point2(self, xptr_str));
1119
+ }
1120
+
1121
+
1122
+ /*
1123
+ * call-seq:
1124
+ * node.prev -> XML::Node
1125
+ *
1126
+ * Obtain the previous sibling, if any.
1127
+ */
1128
+ VALUE
1129
+ ruby_xml_node_prev_get(VALUE self) {
1130
+ xmlNodePtr xnode;
1131
+ xmlNodePtr node;
1132
+ Data_Get_Struct(self, xmlNode, xnode);
1133
+
1134
+ switch (xnode->type) {
1135
+ case XML_DOCUMENT_NODE:
1136
+ #ifdef LIBXML_DOCB_ENABLED
1137
+ case XML_DOCB_DOCUMENT_NODE:
1138
+ #endif
1139
+ case XML_HTML_DOCUMENT_NODE:
1140
+ case XML_NAMESPACE_DECL:
1141
+ node = NULL;
1142
+ break;
1143
+ case XML_ATTRIBUTE_NODE:
1144
+ {
1145
+ xmlAttrPtr attr = (xmlAttrPtr) xnode;
1146
+ node = (xmlNodePtr) attr->prev;
1147
+ }
1148
+ break;
1149
+ default:
1150
+ node = xnode->prev;
1151
+ break;
1152
+ }
1153
+
1154
+ if (node == NULL)
1155
+ return(Qnil);
1156
+ else
1157
+ return(ruby_xml_node2_wrap(cXMLNode, node));
1158
+ }
1159
+
1160
+
1161
+ /*
1162
+ * call-seq:
1163
+ * node.prev = node
1164
+ *
1165
+ * Insert the specified node as this node's previous sibling.
1166
+ */
1167
+ VALUE
1168
+ ruby_xml_node_prev_set(VALUE self, VALUE rnode) {
1169
+ xmlNodePtr cnode, pnode, ret;
1170
+
1171
+ if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
1172
+ rb_raise(rb_eTypeError, "Must pass an XML::Node object");
1173
+
1174
+ Data_Get_Struct(self, xmlNode, pnode);
1175
+ Data_Get_Struct(rnode, xmlNode, cnode);
1176
+
1177
+ ret = xmlAddPrevSibling(pnode, cnode);
1178
+ if (ret == NULL)
1179
+ ruby_xml_raise(&xmlLastError);
1180
+
1181
+ return(ruby_xml_node2_wrap(cXMLNode, ret));
1182
+ }
1183
+
1184
+ /*
1185
+ * call-seq:
1186
+ * node.attributes -> attributes
1187
+ *
1188
+ * Returns the XML::Attributes for this node.
1189
+ */
1190
+ VALUE
1191
+ ruby_xml_node_attributes_get(VALUE self) {
1192
+ xmlNodePtr xnode;
1193
+
1194
+ Data_Get_Struct(self, xmlNode, xnode);
1195
+ return ruby_xml_attributes_new(xnode);
1196
+ }
1197
+
1198
+ /*
1199
+ * call-seq:
1200
+ * node.property("name") -> "string"
1201
+ * node["name"] -> "string"
1202
+ *
1203
+ * Obtain the named pyroperty.
1204
+ */
1205
+ VALUE
1206
+ ruby_xml_node_attribute_get(VALUE self, VALUE name) {
1207
+ VALUE attributes = ruby_xml_node_attributes_get(self);
1208
+ return ruby_xml_attributes_attribute_get(attributes, name);
1209
+ }
1210
+
1211
+ /*
1212
+ * call-seq:
1213
+ * node["name"] = "string"
1214
+ *
1215
+ * Set the named property.
1216
+ */
1217
+ VALUE
1218
+ ruby_xml_node_property_set(VALUE self, VALUE name, VALUE value) {
1219
+ VALUE attributes = ruby_xml_node_attributes_get(self);
1220
+ return ruby_xml_attributes_attribute_set(attributes, name, value);
1221
+ }
1222
+
1223
+
1224
+ /*
1225
+ * call-seq:
1226
+ * node.remove! -> nil
1227
+ *
1228
+ * Removes this node from it's parent.
1229
+ */
1230
+ VALUE
1231
+ ruby_xml_node_remove_ex(VALUE self) {
1232
+ xmlNodePtr xnode;
1233
+ Data_Get_Struct(self, xmlNode, xnode);
1234
+ xmlUnlinkNode(xnode);
1235
+ return(Qnil);
1236
+ }
1237
+
1238
+
1239
+ /*
1240
+ * call-seq:
1241
+ * node.search_href -> namespace
1242
+ *
1243
+ * Search for a namespace by href.
1244
+ */
1245
+ VALUE
1246
+ ruby_xml_node_search_href(VALUE self, VALUE href) {
1247
+ xmlNodePtr xnode;
1248
+
1249
+ Check_Type(href, T_STRING);
1250
+ Data_Get_Struct(self, xmlNode, xnode);
1251
+ return(ruby_xml_ns_wrap(xmlSearchNsByHref(xnode->doc, xnode,
1252
+ (xmlChar*)StringValuePtr(href))));
1253
+ }
1254
+
1255
+
1256
+ /*
1257
+ * call-seq:
1258
+ * node.search_ns -> namespace
1259
+ *
1260
+ * Search for a namespace by namespace.
1261
+ */
1262
+ VALUE
1263
+ ruby_xml_node_search_ns(VALUE self, VALUE ns) {
1264
+ xmlNodePtr xnode;
1265
+
1266
+ Check_Type(ns, T_STRING);
1267
+ Data_Get_Struct(self, xmlNode, xnode);
1268
+ return(ruby_xml_ns_wrap(xmlSearchNs(xnode->doc, xnode,
1269
+ (xmlChar*)StringValuePtr(ns))));
1270
+ }
1271
+
1272
+
1273
+ /*
1274
+ * call-seq:
1275
+ * node.sibling(node) -> XML::Node
1276
+ *
1277
+ * Add the specified node as a sibling of this node.
1278
+ */
1279
+ VALUE
1280
+ ruby_xml_node_sibling_set(VALUE self, VALUE rnode) {
1281
+ xmlNodePtr cnode, pnode, ret;
1282
+ VALUE obj;
1283
+
1284
+ if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
1285
+ rb_raise(rb_eTypeError, "Must pass an XML::Node object");
1286
+
1287
+ Data_Get_Struct(self, xmlNode, pnode);
1288
+ Data_Get_Struct(rnode, xmlNode, cnode);
1289
+
1290
+ ret = xmlAddSibling(pnode, cnode);
1291
+ if (ret == NULL)
1292
+ ruby_xml_raise(&xmlLastError);
1293
+
1294
+ if (ret->_private==NULL)
1295
+ obj=ruby_xml_node2_wrap(cXMLNode,ret);
1296
+ else
1297
+ obj=(VALUE)ret->_private;
1298
+
1299
+ return obj;
1300
+ }
1301
+
1302
+
1303
+ /*
1304
+ * call-seq:
1305
+ * node.space_preserve -> (true|false)
1306
+ *
1307
+ * Determine whether this node preserves whitespace.
1308
+ */
1309
+ VALUE
1310
+ ruby_xml_node_space_preserve_get(VALUE self) {
1311
+ xmlNodePtr xnode;
1312
+
1313
+ Data_Get_Struct(self, xmlNode, xnode);
1314
+ return(INT2NUM(xmlNodeGetSpacePreserve(xnode)));
1315
+ }
1316
+
1317
+
1318
+ /*
1319
+ * call-seq:
1320
+ * node.space_preserve = true|false
1321
+ *
1322
+ * Control whether this node preserves whitespace.
1323
+ */
1324
+ VALUE
1325
+ ruby_xml_node_space_preserve_set(VALUE self, VALUE bool) {
1326
+ xmlNodePtr xnode;
1327
+ Data_Get_Struct(self, xmlNode, xnode);
1328
+
1329
+ if (TYPE(bool) == T_FALSE)
1330
+ xmlNodeSetSpacePreserve(xnode, 1);
1331
+ else
1332
+ xmlNodeSetSpacePreserve(xnode, 0);
1333
+
1334
+ return(Qnil);
1335
+ }
1336
+
1337
+ /*
1338
+ * call-seq:
1339
+ * node.to_s -> "string"
1340
+ *
1341
+ * Coerce this node to a string representation of
1342
+ * it's XML.
1343
+ */
1344
+ VALUE
1345
+ ruby_xml_node_to_s(VALUE self) {
1346
+ xmlNodePtr xnode;
1347
+ xmlBufferPtr buf;
1348
+ VALUE result;
1349
+
1350
+ Data_Get_Struct(self, xmlNode, xnode);
1351
+ buf = xmlBufferCreate();
1352
+ xmlNodeDump(buf, xnode->doc, xnode, 0, 1);
1353
+ result = rb_str_new2((const char*)buf->content);
1354
+
1355
+ xmlBufferFree(buf);
1356
+ return result;
1357
+ }
1358
+
1359
+
1360
+ /*
1361
+ * call-seq:
1362
+ * node.type -> num
1363
+ *
1364
+ * Obtain this node's type identifier.
1365
+ */
1366
+ VALUE
1367
+ ruby_xml_node_type(VALUE self) {
1368
+ xmlNodePtr xnode;
1369
+ Data_Get_Struct(self, xmlNode, xnode);
1370
+ return(INT2NUM(xnode->type));
1371
+ }
1372
+
1373
+
1374
+
1375
+
1376
+ /*
1377
+ * call-seq:
1378
+ * node.copy -> XML::Node
1379
+ *
1380
+ * Creates a copy of this node. To create a
1381
+ * shallow copy set the deep parameter to false.
1382
+ * To create a deep copy set the deep parameter
1383
+ * to true.
1384
+ *
1385
+ */
1386
+ VALUE
1387
+ ruby_xml_node_copy(VALUE self, VALUE deep) {
1388
+ xmlNodePtr xnode;
1389
+ xmlNodePtr xcopy;
1390
+ int recursive = (deep==Qnil || deep==Qfalse) ? 0 : 1;
1391
+ Data_Get_Struct(self, xmlNode, xnode);
1392
+
1393
+ xcopy = xmlCopyNode(xnode, recursive);
1394
+
1395
+ if (xcopy)
1396
+ return ruby_xml_node2_wrap(cXMLNode, xcopy);
1397
+ else
1398
+ return Qnil;
1399
+ }
1400
+
1401
+ /*
1402
+ * call-seq:
1403
+ * XML::Node.new_text(content = nil) -> XML::Node
1404
+ *
1405
+ * Create a new text node, optionally setting
1406
+ * the node's content.
1407
+ *
1408
+ */
1409
+ VALUE
1410
+ ruby_xml_node_new_text(VALUE class, VALUE text)
1411
+ {
1412
+ VALUE obj;
1413
+ xmlNodePtr xnode;
1414
+
1415
+ if ( NIL_P(text) )
1416
+ return Qnil;
1417
+
1418
+ if (TYPE(text) != T_STRING )
1419
+ rb_raise(rb_eTypeError, "requires string argument");
1420
+
1421
+ xnode=xmlNewText((xmlChar*)STR2CSTR(text));
1422
+ if ( xnode == NULL )
1423
+ return Qnil;
1424
+
1425
+ obj=ruby_xml_node2_wrap(class,xnode);
1426
+ rb_obj_call_init(obj,0,NULL);
1427
+ return obj;
1428
+ }
1429
+
1430
+ void
1431
+ ruby_xml_node_registerNode(xmlNodePtr node)
1432
+ {
1433
+ node->_private=NULL;
1434
+ }
1435
+
1436
+ void
1437
+ ruby_xml_node_deregisterNode(xmlNodePtr xnode)
1438
+ {
1439
+ VALUE node;
1440
+
1441
+ if (xnode->_private==NULL ) return;
1442
+ node = (VALUE)xnode->_private;
1443
+ DATA_PTR(node) = NULL;
1444
+ }
1445
+
1446
+ // Rdoc needs to know
1447
+ #ifdef RDOC_NEVER_DEFINED
1448
+ mLibXML = rb_define_module("LibXML");
1449
+ mXML = rb_define_module_under(mLibXML, "XML");
1450
+ #endif
1451
+
1452
+ void
1453
+ ruby_init_xml_node(void) {
1454
+ xmlRegisterNodeDefault(ruby_xml_node_registerNode);
1455
+ xmlDeregisterNodeDefault(ruby_xml_node_deregisterNode);
1456
+
1457
+ cXMLNode = rb_define_class_under(mXML, "Node", rb_cObject);
1458
+
1459
+ rb_define_const(cXMLNode, "SPACE_DEFAULT", INT2NUM(0));
1460
+ rb_define_const(cXMLNode, "SPACE_PRESERVE", INT2NUM(1));
1461
+ rb_define_const(cXMLNode, "SPACE_NOT_INHERIT", INT2NUM(-1));
1462
+ rb_define_const(cXMLNode, "XLINK_ACTUATE_AUTO", INT2NUM(1));
1463
+ rb_define_const(cXMLNode, "XLINK_ACTUATE_NONE", INT2NUM(0));
1464
+ rb_define_const(cXMLNode, "XLINK_ACTUATE_ONREQUEST", INT2NUM(2));
1465
+ rb_define_const(cXMLNode, "XLINK_SHOW_EMBED", INT2NUM(2));
1466
+ rb_define_const(cXMLNode, "XLINK_SHOW_NEW", INT2NUM(1));
1467
+ rb_define_const(cXMLNode, "XLINK_SHOW_NONE", INT2NUM(0));
1468
+ rb_define_const(cXMLNode, "XLINK_SHOW_REPLACE", INT2NUM(3));
1469
+ rb_define_const(cXMLNode, "XLINK_TYPE_EXTENDED", INT2NUM(2));
1470
+ rb_define_const(cXMLNode, "XLINK_TYPE_EXTENDED_SET", INT2NUM(3));
1471
+ rb_define_const(cXMLNode, "XLINK_TYPE_NONE", INT2NUM(0));
1472
+ rb_define_const(cXMLNode, "XLINK_TYPE_SIMPLE", INT2NUM(1));
1473
+
1474
+ rb_define_const(cXMLNode, "ELEMENT_NODE", INT2FIX(XML_ELEMENT_NODE));
1475
+ rb_define_const(cXMLNode, "ATTRIBUTE_NODE", INT2FIX(XML_ATTRIBUTE_NODE));
1476
+ rb_define_const(cXMLNode, "TEXT_NODE", INT2FIX(XML_TEXT_NODE));
1477
+ rb_define_const(cXMLNode, "CDATA_SECTION_NODE", INT2FIX(XML_CDATA_SECTION_NODE));
1478
+ rb_define_const(cXMLNode, "ENTITY_REF_NODE", INT2FIX(XML_ENTITY_REF_NODE));
1479
+ rb_define_const(cXMLNode, "ENTITY_NODE", INT2FIX(XML_ENTITY_NODE));
1480
+ rb_define_const(cXMLNode, "PI_NODE", INT2FIX(XML_PI_NODE));
1481
+ rb_define_const(cXMLNode, "COMMENT_NODE", INT2FIX(XML_COMMENT_NODE));
1482
+ rb_define_const(cXMLNode, "DOCUMENT_NODE", INT2FIX(XML_DOCUMENT_NODE));
1483
+ rb_define_const(cXMLNode, "DOCUMENT_TYPE_NODE", INT2FIX(XML_DOCUMENT_TYPE_NODE));
1484
+ rb_define_const(cXMLNode, "DOCUMENT_FRAG_NODE", INT2FIX(XML_DOCUMENT_FRAG_NODE));
1485
+ rb_define_const(cXMLNode, "NOTATION_NODE", INT2FIX(XML_NOTATION_NODE));
1486
+ rb_define_const(cXMLNode, "HTML_DOCUMENT_NODE", INT2FIX(XML_HTML_DOCUMENT_NODE));
1487
+ rb_define_const(cXMLNode, "DTD_NODE", INT2FIX(XML_DTD_NODE));
1488
+ rb_define_const(cXMLNode, "ELEMENT_DECL", INT2FIX(XML_ELEMENT_DECL));
1489
+ rb_define_const(cXMLNode, "ATTRIBUTE_DECL", INT2FIX(XML_ATTRIBUTE_DECL));
1490
+ rb_define_const(cXMLNode, "ENTITY_DECL", INT2FIX(XML_ENTITY_DECL));
1491
+ rb_define_const(cXMLNode, "NAMESPACE_DECL", INT2FIX(XML_NAMESPACE_DECL));
1492
+ rb_define_const(cXMLNode, "XINCLUDE_START", INT2FIX(XML_XINCLUDE_START));
1493
+ rb_define_const(cXMLNode, "XINCLUDE_END", INT2FIX(XML_XINCLUDE_END));
1494
+
1495
+ #ifdef LIBXML_DOCB_ENABLED
1496
+ rb_define_const(cXMLNode, "DOCB_DOCUMENT_NODE", INT2FIX(XML_DOCB_DOCUMENT_NODE));
1497
+ #else
1498
+ rb_define_const(cXMLNode, "DOCB_DOCUMENT_NODE", Qnil);
1499
+ #endif
1500
+
1501
+ rb_define_singleton_method(cXMLNode, "new", ruby_xml_node_new_string_bc, -1);
1502
+ rb_define_singleton_method(cXMLNode, "new_cdata", ruby_xml_node_new_cdata, -1);
1503
+ rb_define_singleton_method(cXMLNode, "new_comment", ruby_xml_node_new_comment, -1);
1504
+ rb_define_singleton_method(cXMLNode, "new_text", ruby_xml_node_new_text, 1);
1505
+
1506
+ /* Traversal */
1507
+ rb_include_module(cXMLNode, rb_mEnumerable);
1508
+ rb_define_method(cXMLNode, "[]", ruby_xml_node_attribute_get, 1);
1509
+ rb_define_method(cXMLNode, "each", ruby_xml_node_each, 0);
1510
+ rb_define_method(cXMLNode, "first", ruby_xml_node_first_get, 0);
1511
+ rb_define_method(cXMLNode, "last", ruby_xml_node_last_get, 0);
1512
+ rb_define_method(cXMLNode, "next", ruby_xml_node_next_get, 0);
1513
+ rb_define_method(cXMLNode, "parent", ruby_xml_node_parent_get, 0);
1514
+ rb_define_method(cXMLNode, "prev", ruby_xml_node_prev_get, 0);
1515
+
1516
+ /* Modification */
1517
+ rb_define_method(cXMLNode, "<<", ruby_xml_node_content_add, 1);
1518
+ rb_define_method(cXMLNode, "[]=", ruby_xml_node_property_set, 2);
1519
+ rb_define_method(cXMLNode, "child_add", ruby_xml_node_child_add, 1);
1520
+ rb_define_method(cXMLNode, "child=", ruby_xml_node_child_set, 1);
1521
+ rb_define_method(cXMLNode, "sibling=", ruby_xml_node_sibling_set, 1);
1522
+ rb_define_method(cXMLNode, "next=", ruby_xml_node_next_set, 1);
1523
+ rb_define_method(cXMLNode, "prev=", ruby_xml_node_prev_set, 1);
1524
+
1525
+
1526
+ /* Rest of the node api */
1527
+ rb_define_method(cXMLNode, "attributes", ruby_xml_node_attributes_get, 0);
1528
+ rb_define_method(cXMLNode, "base", ruby_xml_node_base_get, 0);
1529
+ rb_define_method(cXMLNode, "base=", ruby_xml_node_base_set, 1);
1530
+ rb_define_method(cXMLNode, "blank?", ruby_xml_node_empty_q, 0);
1531
+ rb_define_method(cXMLNode, "copy", ruby_xml_node_copy, 1);
1532
+ rb_define_method(cXMLNode, "content", ruby_xml_node_content_get, 0);
1533
+ rb_define_method(cXMLNode, "content=", ruby_xml_node_content_set, 1);
1534
+ rb_define_method(cXMLNode, "content_stripped", ruby_xml_node_content_stripped_get, 0);
1535
+ rb_define_method(cXMLNode, "doc", ruby_xml_node_doc, 0);
1536
+ rb_define_method(cXMLNode, "dump", ruby_xml_node_dump, 0);
1537
+ rb_define_method(cXMLNode, "debug_dump", ruby_xml_node_debug_dump, 0);
1538
+ rb_define_method(cXMLNode, "empty?", ruby_xml_node_empty_q, 0);
1539
+ rb_define_method(cXMLNode, "eql?", ruby_xml_node_eql_q, 1);
1540
+ rb_define_method(cXMLNode, "lang", ruby_xml_node_lang_get, 0);
1541
+ rb_define_method(cXMLNode, "lang=", ruby_xml_node_lang_set, 1);
1542
+ rb_define_method(cXMLNode, "line_num", ruby_xml_node_line_num, 0);
1543
+ rb_define_method(cXMLNode, "name", ruby_xml_node_name_get, 0);
1544
+ rb_define_method(cXMLNode, "name=", ruby_xml_node_name_set, 1);
1545
+ rb_define_method(cXMLNode, "namespace", ruby_xml_node_namespace_get, 0);
1546
+ rb_define_method(cXMLNode, "namespace_node", ruby_xml_node_namespace_get_node, 0);
1547
+ rb_define_method(cXMLNode, "namespace=", ruby_xml_node_namespace_set, -1);
1548
+ rb_define_method(cXMLNode, "node_type", ruby_xml_node_type, 0);
1549
+ rb_define_method(cXMLNode, "ns", ruby_xml_node_namespace_get, 0);
1550
+ rb_define_method(cXMLNode, "ns?", ruby_xml_node_ns_q, 0);
1551
+ rb_define_method(cXMLNode, "ns_def?", ruby_xml_node_ns_def_q, 0);
1552
+ rb_define_method(cXMLNode, "ns_def", ruby_xml_node_ns_def_get, 0);
1553
+ rb_define_method(cXMLNode, "path", ruby_xml_node_path, 0);
1554
+ rb_define_method(cXMLNode, "pointer", ruby_xml_node_pointer, 1);
1555
+ rb_define_method(cXMLNode, "remove!", ruby_xml_node_remove_ex, 0);
1556
+ rb_define_method(cXMLNode, "search_ns", ruby_xml_node_search_ns, 1);
1557
+ rb_define_method(cXMLNode, "search_href", ruby_xml_node_search_href, 1);
1558
+ rb_define_method(cXMLNode, "space_preserve", ruby_xml_node_space_preserve_get, 0);
1559
+ rb_define_method(cXMLNode, "space_preserve=", ruby_xml_node_space_preserve_set, 1);
1560
+ rb_define_method(cXMLNode, "to_s", ruby_xml_node_to_s, 0);
1561
+ rb_define_method(cXMLNode, "xlink?", ruby_xml_node_xlink_q, 0);
1562
+ rb_define_method(cXMLNode, "xlink_type", ruby_xml_node_xlink_type, 0);
1563
+ rb_define_method(cXMLNode, "xlink_type_name", ruby_xml_node_xlink_type_name, 0);
1564
+
1565
+ rb_define_alias(cXMLNode, "==", "eql?");
1566
+ }