libxml-ruby 3.2.2-x64-mingw-ucrt

Sign up to get free protection for your applications and to get access to all the features.
Files changed (205) hide show
  1. checksums.yaml +7 -0
  2. data/HISTORY +848 -0
  3. data/LICENSE +21 -0
  4. data/MANIFEST +166 -0
  5. data/README.rdoc +217 -0
  6. data/Rakefile +99 -0
  7. data/ext/libxml/extconf.rb +61 -0
  8. data/ext/libxml/libxml.c +80 -0
  9. data/ext/libxml/libxml_ruby.def +35 -0
  10. data/ext/libxml/ruby_libxml.h +67 -0
  11. data/ext/libxml/ruby_xml.c +933 -0
  12. data/ext/libxml/ruby_xml.h +10 -0
  13. data/ext/libxml/ruby_xml_attr.c +333 -0
  14. data/ext/libxml/ruby_xml_attr.h +12 -0
  15. data/ext/libxml/ruby_xml_attr_decl.c +153 -0
  16. data/ext/libxml/ruby_xml_attr_decl.h +11 -0
  17. data/ext/libxml/ruby_xml_attributes.c +275 -0
  18. data/ext/libxml/ruby_xml_attributes.h +15 -0
  19. data/ext/libxml/ruby_xml_cbg.c +85 -0
  20. data/ext/libxml/ruby_xml_document.c +1123 -0
  21. data/ext/libxml/ruby_xml_document.h +11 -0
  22. data/ext/libxml/ruby_xml_dtd.c +248 -0
  23. data/ext/libxml/ruby_xml_dtd.h +9 -0
  24. data/ext/libxml/ruby_xml_encoding.c +250 -0
  25. data/ext/libxml/ruby_xml_encoding.h +16 -0
  26. data/ext/libxml/ruby_xml_error.c +996 -0
  27. data/ext/libxml/ruby_xml_error.h +12 -0
  28. data/ext/libxml/ruby_xml_html_parser.c +89 -0
  29. data/ext/libxml/ruby_xml_html_parser.h +10 -0
  30. data/ext/libxml/ruby_xml_html_parser_context.c +337 -0
  31. data/ext/libxml/ruby_xml_html_parser_context.h +10 -0
  32. data/ext/libxml/ruby_xml_html_parser_options.c +46 -0
  33. data/ext/libxml/ruby_xml_html_parser_options.h +10 -0
  34. data/ext/libxml/ruby_xml_input_cbg.c +191 -0
  35. data/ext/libxml/ruby_xml_input_cbg.h +20 -0
  36. data/ext/libxml/ruby_xml_io.c +47 -0
  37. data/ext/libxml/ruby_xml_io.h +10 -0
  38. data/ext/libxml/ruby_xml_namespace.c +153 -0
  39. data/ext/libxml/ruby_xml_namespace.h +10 -0
  40. data/ext/libxml/ruby_xml_namespaces.c +293 -0
  41. data/ext/libxml/ruby_xml_namespaces.h +9 -0
  42. data/ext/libxml/ruby_xml_node.c +1402 -0
  43. data/ext/libxml/ruby_xml_node.h +13 -0
  44. data/ext/libxml/ruby_xml_parser.c +91 -0
  45. data/ext/libxml/ruby_xml_parser.h +12 -0
  46. data/ext/libxml/ruby_xml_parser_context.c +999 -0
  47. data/ext/libxml/ruby_xml_parser_context.h +10 -0
  48. data/ext/libxml/ruby_xml_parser_options.c +66 -0
  49. data/ext/libxml/ruby_xml_parser_options.h +12 -0
  50. data/ext/libxml/ruby_xml_reader.c +1239 -0
  51. data/ext/libxml/ruby_xml_reader.h +17 -0
  52. data/ext/libxml/ruby_xml_relaxng.c +110 -0
  53. data/ext/libxml/ruby_xml_relaxng.h +10 -0
  54. data/ext/libxml/ruby_xml_sax2_handler.c +326 -0
  55. data/ext/libxml/ruby_xml_sax2_handler.h +10 -0
  56. data/ext/libxml/ruby_xml_sax_parser.c +116 -0
  57. data/ext/libxml/ruby_xml_sax_parser.h +10 -0
  58. data/ext/libxml/ruby_xml_schema.c +278 -0
  59. data/ext/libxml/ruby_xml_schema.h +809 -0
  60. data/ext/libxml/ruby_xml_schema_attribute.c +109 -0
  61. data/ext/libxml/ruby_xml_schema_attribute.h +15 -0
  62. data/ext/libxml/ruby_xml_schema_element.c +95 -0
  63. data/ext/libxml/ruby_xml_schema_element.h +14 -0
  64. data/ext/libxml/ruby_xml_schema_facet.c +52 -0
  65. data/ext/libxml/ruby_xml_schema_facet.h +13 -0
  66. data/ext/libxml/ruby_xml_schema_type.c +232 -0
  67. data/ext/libxml/ruby_xml_schema_type.h +9 -0
  68. data/ext/libxml/ruby_xml_version.h +9 -0
  69. data/ext/libxml/ruby_xml_writer.c +1133 -0
  70. data/ext/libxml/ruby_xml_writer.h +10 -0
  71. data/ext/libxml/ruby_xml_xinclude.c +16 -0
  72. data/ext/libxml/ruby_xml_xinclude.h +11 -0
  73. data/ext/libxml/ruby_xml_xpath.c +194 -0
  74. data/ext/libxml/ruby_xml_xpath.h +13 -0
  75. data/ext/libxml/ruby_xml_xpath_context.c +360 -0
  76. data/ext/libxml/ruby_xml_xpath_context.h +9 -0
  77. data/ext/libxml/ruby_xml_xpath_expression.c +81 -0
  78. data/ext/libxml/ruby_xml_xpath_expression.h +10 -0
  79. data/ext/libxml/ruby_xml_xpath_object.c +338 -0
  80. data/ext/libxml/ruby_xml_xpath_object.h +17 -0
  81. data/ext/libxml/ruby_xml_xpointer.c +99 -0
  82. data/ext/libxml/ruby_xml_xpointer.h +11 -0
  83. data/ext/vc/libxml_ruby.sln +28 -0
  84. data/lib/3.1/libxml_ruby.so +0 -0
  85. data/lib/libxml/attr.rb +123 -0
  86. data/lib/libxml/attr_decl.rb +80 -0
  87. data/lib/libxml/attributes.rb +14 -0
  88. data/lib/libxml/document.rb +194 -0
  89. data/lib/libxml/error.rb +95 -0
  90. data/lib/libxml/hpricot.rb +78 -0
  91. data/lib/libxml/html_parser.rb +96 -0
  92. data/lib/libxml/namespace.rb +62 -0
  93. data/lib/libxml/namespaces.rb +38 -0
  94. data/lib/libxml/node.rb +323 -0
  95. data/lib/libxml/parser.rb +101 -0
  96. data/lib/libxml/sax_callbacks.rb +180 -0
  97. data/lib/libxml/sax_parser.rb +41 -0
  98. data/lib/libxml/schema/attribute.rb +19 -0
  99. data/lib/libxml/schema/element.rb +19 -0
  100. data/lib/libxml/schema/type.rb +21 -0
  101. data/lib/libxml/schema.rb +48 -0
  102. data/lib/libxml/tree.rb +29 -0
  103. data/lib/libxml-ruby.rb +30 -0
  104. data/lib/libxml.rb +5 -0
  105. data/lib/xml/libxml.rb +10 -0
  106. data/lib/xml.rb +14 -0
  107. data/libxml-ruby.gemspec +48 -0
  108. data/script/benchmark/depixelate +634 -0
  109. data/script/benchmark/hamlet.xml +9055 -0
  110. data/script/benchmark/parsecount +170 -0
  111. data/script/benchmark/sock_entries.xml +507 -0
  112. data/script/benchmark/throughput +41 -0
  113. data/script/test +6 -0
  114. data/setup.rb +1584 -0
  115. data/test/c14n/given/doc.dtd +1 -0
  116. data/test/c14n/given/example-1.xml +14 -0
  117. data/test/c14n/given/example-2.xml +11 -0
  118. data/test/c14n/given/example-3.xml +18 -0
  119. data/test/c14n/given/example-4.xml +9 -0
  120. data/test/c14n/given/example-5.xml +12 -0
  121. data/test/c14n/given/example-6.xml +2 -0
  122. data/test/c14n/given/example-7.xml +11 -0
  123. data/test/c14n/given/example-8.xml +11 -0
  124. data/test/c14n/given/example-8.xpath +10 -0
  125. data/test/c14n/given/world.txt +1 -0
  126. data/test/c14n/result/1-1-without-comments/example-1 +4 -0
  127. data/test/c14n/result/1-1-without-comments/example-2 +11 -0
  128. data/test/c14n/result/1-1-without-comments/example-3 +14 -0
  129. data/test/c14n/result/1-1-without-comments/example-4 +9 -0
  130. data/test/c14n/result/1-1-without-comments/example-5 +3 -0
  131. data/test/c14n/result/1-1-without-comments/example-6 +1 -0
  132. data/test/c14n/result/1-1-without-comments/example-7 +1 -0
  133. data/test/c14n/result/1-1-without-comments/example-8 +1 -0
  134. data/test/c14n/result/with-comments/example-1 +6 -0
  135. data/test/c14n/result/with-comments/example-2 +11 -0
  136. data/test/c14n/result/with-comments/example-3 +14 -0
  137. data/test/c14n/result/with-comments/example-4 +9 -0
  138. data/test/c14n/result/with-comments/example-5 +4 -0
  139. data/test/c14n/result/with-comments/example-6 +1 -0
  140. data/test/c14n/result/with-comments/example-7 +1 -0
  141. data/test/c14n/result/without-comments/example-1 +4 -0
  142. data/test/c14n/result/without-comments/example-2 +11 -0
  143. data/test/c14n/result/without-comments/example-3 +14 -0
  144. data/test/c14n/result/without-comments/example-4 +9 -0
  145. data/test/c14n/result/without-comments/example-5 +3 -0
  146. data/test/c14n/result/without-comments/example-6 +1 -0
  147. data/test/c14n/result/without-comments/example-7 +1 -0
  148. data/test/model/atom.xml +13 -0
  149. data/test/model/bands.iso-8859-1.xml +5 -0
  150. data/test/model/bands.utf-8.xml +5 -0
  151. data/test/model/bands.xml +5 -0
  152. data/test/model/books.xml +154 -0
  153. data/test/model/cwm_1_0.xml +11336 -0
  154. data/test/model/merge_bug_data.xml +58 -0
  155. data/test/model/ruby-lang.html +238 -0
  156. data/test/model/rubynet.xml +79 -0
  157. data/test/model/rubynet_project +1 -0
  158. data/test/model/shiporder.rnc +28 -0
  159. data/test/model/shiporder.rng +86 -0
  160. data/test/model/shiporder.xml +23 -0
  161. data/test/model/shiporder.xsd +40 -0
  162. data/test/model/soap.xml +27 -0
  163. data/test/model/xinclude.xml +5 -0
  164. data/test/test_attr.rb +181 -0
  165. data/test/test_attr_decl.rb +132 -0
  166. data/test/test_attributes.rb +136 -0
  167. data/test/test_canonicalize.rb +120 -0
  168. data/test/test_deprecated_require.rb +12 -0
  169. data/test/test_document.rb +132 -0
  170. data/test/test_document_write.rb +146 -0
  171. data/test/test_dtd.rb +129 -0
  172. data/test/test_encoding.rb +129 -0
  173. data/test/test_encoding_sax.rb +115 -0
  174. data/test/test_error.rb +178 -0
  175. data/test/test_helper.rb +9 -0
  176. data/test/test_html_parser.rb +162 -0
  177. data/test/test_html_parser_context.rb +23 -0
  178. data/test/test_namespace.rb +60 -0
  179. data/test/test_namespaces.rb +200 -0
  180. data/test/test_node.rb +237 -0
  181. data/test/test_node_cdata.rb +50 -0
  182. data/test/test_node_comment.rb +32 -0
  183. data/test/test_node_copy.rb +40 -0
  184. data/test/test_node_edit.rb +158 -0
  185. data/test/test_node_pi.rb +37 -0
  186. data/test/test_node_text.rb +69 -0
  187. data/test/test_node_write.rb +97 -0
  188. data/test/test_node_xlink.rb +28 -0
  189. data/test/test_parser.rb +324 -0
  190. data/test/test_parser_context.rb +198 -0
  191. data/test/test_properties.rb +38 -0
  192. data/test/test_reader.rb +364 -0
  193. data/test/test_relaxng.rb +53 -0
  194. data/test/test_sax_parser.rb +326 -0
  195. data/test/test_schema.rb +168 -0
  196. data/test/test_suite.rb +48 -0
  197. data/test/test_traversal.rb +152 -0
  198. data/test/test_writer.rb +468 -0
  199. data/test/test_xinclude.rb +20 -0
  200. data/test/test_xml.rb +263 -0
  201. data/test/test_xpath.rb +244 -0
  202. data/test/test_xpath_context.rb +88 -0
  203. data/test/test_xpath_expression.rb +37 -0
  204. data/test/test_xpointer.rb +72 -0
  205. metadata +325 -0
@@ -0,0 +1,1239 @@
1
+ /* Copyright (c) 2006-2007 Apple Inc.
2
+ * Please see the LICENSE file for copyright and distribution information. */
3
+
4
+ #include "ruby_libxml.h"
5
+ #include "ruby_xml_reader.h"
6
+
7
+ /*
8
+ * Document-class: LibXML::XML::Reader
9
+ *
10
+ * The XML::Reader class provides a simpler, alternative way of parsing an XML
11
+ * document in contrast to XML::Parser or XML::SaxParser. A XML::Reader instance
12
+ * acts like a cursor going forward in a document stream, stopping at each node
13
+ * it encounters. To advance to the next node, simply cadd XML::Reader#read.
14
+ *
15
+ * The XML::Reader API closely matches the DOM Core specification and supports
16
+ * namespaces, xml:base, entity handling and DTDs.
17
+ *
18
+ * To summarize, XML::Reader provides a far simpler API to use versus XML::SaxParser
19
+ * and is more memory efficient than using XML::Parser to create a DOM tree.
20
+ *
21
+ * Example:
22
+ *
23
+ * reader = XML::Reader.string("<foo><bar>1</bar><bar>2</bar><bar>3</bar></foo>")
24
+ * reader.read
25
+ * assert_equal('foo', reader.name)
26
+ * assert_nil(reader.value)
27
+ *
28
+ * 3.times do |i|
29
+ * reader.read
30
+ * assert_equal(XML::Reader::TYPE_ELEMENT, reader.node_type)
31
+ * assert_equal('bar', reader.name)
32
+ * reader.read
33
+ * assert_equal(XML::Reader::TYPE_TEXT, reader.node_type)
34
+ * assert_equal((i + 1).to_s, reader.value)
35
+ * reader.read
36
+ * assert_equal(XML::Reader::TYPE_END_ELEMENT, reader.node_type)
37
+ * end
38
+ *
39
+ * You can also parse documents (see XML::Reader.document),
40
+ * strings (see XML::Parser.string) and io objects (see
41
+ * XML::Parser.io).
42
+ *
43
+ * For a more in depth tutorial, albeit in C, see http://xmlsoft.org/xmlreader.html.*/
44
+
45
+
46
+ /* NOTE - We need to wrap the readers document to support Reader.read.node.find('/').
47
+ To do this we need to use xmlTextReaderCurrentDoc which means we have to free the
48
+ document ourselves. Annoying... */
49
+
50
+ VALUE cXMLReader;
51
+
52
+ static ID BASE_URI_SYMBOL;
53
+ static ID ENCODING_SYMBOL;
54
+ static ID IO_ATTR;
55
+ static ID OPTIONS_SYMBOL;
56
+
57
+ static void rxml_reader_free(xmlTextReaderPtr xreader)
58
+ {
59
+ xmlFreeTextReader(xreader);
60
+ }
61
+
62
+ static void rxml_reader_mark(xmlTextReaderPtr xreader)
63
+ {
64
+ xmlDocPtr xdoc = xmlTextReaderCurrentDoc(xreader);
65
+ VALUE doc = (VALUE)xdoc->_private;
66
+ rb_gc_mark(doc);
67
+ }
68
+
69
+ static VALUE rxml_reader_wrap(xmlTextReaderPtr xreader)
70
+ {
71
+ return Data_Wrap_Struct(cXMLReader, NULL, rxml_reader_free, xreader);
72
+ }
73
+
74
+
75
+ static xmlTextReaderPtr rxml_text_reader_get(VALUE obj)
76
+ {
77
+ xmlTextReaderPtr xreader;
78
+ Data_Get_Struct(obj, xmlTextReader, xreader);
79
+ return xreader;
80
+ }
81
+
82
+ /*
83
+ * call-seq:
84
+ * XML::Reader.document(doc) -> XML::Reader
85
+ *
86
+ * Create an new reader for the specified document.
87
+ */
88
+ VALUE rxml_reader_document(VALUE klass, VALUE doc)
89
+ {
90
+ xmlDocPtr xdoc;
91
+ xmlTextReaderPtr xreader;
92
+
93
+ Data_Get_Struct(doc, xmlDoc, xdoc);
94
+
95
+ xreader = xmlReaderWalker(xdoc);
96
+
97
+ if (xreader == NULL)
98
+ rxml_raise(&xmlLastError);
99
+
100
+ return rxml_reader_wrap(xreader);
101
+ }
102
+
103
+ /* call-seq:
104
+ * XML::Reader.file(path) -> XML::Reader
105
+ * XML::Reader.file(path, :encoding => XML::Encoding::UTF_8,
106
+ * :options => XML::Parser::Options::NOENT) -> XML::Parser
107
+ *
108
+ * Creates a new reader by parsing the specified file or uri.
109
+ *
110
+ * You may provide an optional hash table to control how the
111
+ * parsing is performed. Valid options are:
112
+ *
113
+ * encoding - The document encoding, defaults to nil. Valid values
114
+ * are the encoding constants defined on XML::Encoding.
115
+ * options - Controls the execution of the parser, defaults to 0.
116
+ * Valid values are the constants defined on
117
+ * XML::Parser::Options. Mutliple options can be combined
118
+ * by using Bitwise OR (|).
119
+ */
120
+ static VALUE rxml_reader_file(int argc, VALUE *argv, VALUE klass)
121
+ {
122
+ xmlTextReaderPtr xreader;
123
+ VALUE path;
124
+ VALUE options;
125
+
126
+ const char *xencoding = NULL;
127
+ int xoptions = 0;
128
+
129
+ rb_scan_args(argc, argv, "11", &path, &options);
130
+ Check_Type(path, T_STRING);
131
+
132
+ if (!NIL_P(options))
133
+ {
134
+ VALUE encoding = Qnil;
135
+ VALUE parserOptions = Qnil;
136
+
137
+ Check_Type(options, T_HASH);
138
+
139
+ encoding = rb_hash_aref(options, BASE_URI_SYMBOL);
140
+ xencoding = NIL_P(encoding) ? NULL : xmlGetCharEncodingName(NUM2INT(encoding));
141
+
142
+ parserOptions = rb_hash_aref(options, OPTIONS_SYMBOL);
143
+ xoptions = NIL_P(parserOptions) ? 0 : NUM2INT(parserOptions);
144
+ }
145
+
146
+ xreader = xmlReaderForFile(StringValueCStr(path), xencoding, xoptions);
147
+
148
+ if (xreader == NULL)
149
+ rxml_raise(&xmlLastError);
150
+
151
+ return rxml_reader_wrap(xreader);
152
+ }
153
+
154
+ /* call-seq:
155
+ * XML::Reader.io(io) -> XML::Reader
156
+ * XML::Reader.io(io, :encoding => XML::Encoding::UTF_8,
157
+ * :options => XML::Parser::Options::NOENT) -> XML::Parser
158
+ *
159
+ * Creates a new reader by parsing the specified io object.
160
+ *
161
+ * You may provide an optional hash table to control how the
162
+ * parsing is performed. Valid options are:
163
+ *
164
+ * base_uri - The base url for the parsed document.
165
+ * encoding - The document encoding, defaults to nil. Valid values
166
+ * are the encoding constants defined on XML::Encoding.
167
+ * options - Controls the execution of the parser, defaults to 0.
168
+ * Valid values are the constants defined on
169
+ * XML::Parser::Options. Mutliple options can be combined
170
+ * by using Bitwise OR (|).
171
+ */
172
+ static VALUE rxml_reader_io(int argc, VALUE *argv, VALUE klass)
173
+ {
174
+ xmlTextReaderPtr xreader;
175
+ VALUE result;
176
+ VALUE io;
177
+ VALUE options;
178
+ char *xbaseurl = NULL;
179
+ const char *xencoding = NULL;
180
+ int xoptions = 0;
181
+
182
+ rb_scan_args(argc, argv, "11", &io, &options);
183
+
184
+ if (!NIL_P(options))
185
+ {
186
+ VALUE baseurl = Qnil;
187
+ VALUE encoding = Qnil;
188
+ VALUE parserOptions = Qnil;
189
+
190
+ Check_Type(options, T_HASH);
191
+
192
+ baseurl = rb_hash_aref(options, BASE_URI_SYMBOL);
193
+ xbaseurl = NIL_P(baseurl) ? NULL : StringValueCStr(baseurl);
194
+
195
+ encoding = rb_hash_aref(options, ENCODING_SYMBOL);
196
+ xencoding = NIL_P(encoding) ? NULL : xmlGetCharEncodingName(NUM2INT(encoding));
197
+
198
+ parserOptions = rb_hash_aref(options, OPTIONS_SYMBOL);
199
+ xoptions = NIL_P(parserOptions) ? 0 : NUM2INT(parserOptions);
200
+ }
201
+
202
+ xreader = xmlReaderForIO((xmlInputReadCallback) rxml_read_callback, NULL,
203
+ (void *) io,
204
+ xbaseurl, xencoding, xoptions);
205
+
206
+ if (xreader == NULL)
207
+ rxml_raise(&xmlLastError);
208
+
209
+ result = rxml_reader_wrap(xreader);
210
+
211
+ /* Attach io object to parser so it won't get freed.*/
212
+ rb_ivar_set(result, IO_ATTR, io);
213
+
214
+ return result;
215
+ }
216
+
217
+ /* call-seq:
218
+ * XML::Reader.string(io) -> XML::Reader
219
+ * XML::Reader.string(io, :encoding => XML::Encoding::UTF_8,
220
+ * :options => XML::Parser::Options::NOENT) -> XML::Parser
221
+ *
222
+ * Creates a new reader by parsing the specified string.
223
+ *
224
+ * You may provide an optional hash table to control how the
225
+ * parsing is performed. Valid options are:
226
+ *
227
+ * base_uri - The base url for the parsed document.
228
+ * encoding - The document encoding, defaults to nil. Valid values
229
+ * are the encoding constants defined on XML::Encoding.
230
+ * options - Controls the execution of the parser, defaults to 0.
231
+ * Valid values are the constants defined on
232
+ * XML::Parser::Options. Mutliple options can be combined
233
+ * by using Bitwise OR (|).
234
+ */
235
+ static VALUE rxml_reader_string(int argc, VALUE *argv, VALUE klass)
236
+ {
237
+ xmlTextReaderPtr xreader;
238
+ VALUE string;
239
+ VALUE options;
240
+ char *xbaseurl = NULL;
241
+ const char *xencoding = NULL;
242
+ int xoptions = 0;
243
+
244
+ rb_scan_args(argc, argv, "11", &string, &options);
245
+ Check_Type(string, T_STRING);
246
+
247
+ if (!NIL_P(options))
248
+ {
249
+ VALUE baseurl = Qnil;
250
+ VALUE encoding = Qnil;
251
+ VALUE parserOptions = Qnil;
252
+
253
+ Check_Type(options, T_HASH);
254
+
255
+ baseurl = rb_hash_aref(options, BASE_URI_SYMBOL);
256
+ xbaseurl = NIL_P(baseurl) ? NULL : StringValueCStr(baseurl);
257
+
258
+ encoding = rb_hash_aref(options, ENCODING_SYMBOL);
259
+ xencoding = NIL_P(encoding) ? NULL : xmlGetCharEncodingName(NUM2INT(encoding));
260
+
261
+ parserOptions = rb_hash_aref(options, OPTIONS_SYMBOL);
262
+ xoptions = NIL_P(parserOptions) ? 0 : NUM2INT(parserOptions);
263
+ }
264
+
265
+ xreader = xmlReaderForMemory(StringValueCStr(string), (int)RSTRING_LEN(string),
266
+ xbaseurl, xencoding, xoptions);
267
+
268
+ if (xreader == NULL)
269
+ rxml_raise(&xmlLastError);
270
+
271
+ return rxml_reader_wrap(xreader);
272
+ }
273
+
274
+ /*
275
+ * call-seq:
276
+ * reader.close -> code
277
+ *
278
+ * This method releases any resources allocated by the current instance
279
+ * changes the state to Closed and close any underlying input.
280
+ */
281
+ static VALUE rxml_reader_close(VALUE self)
282
+ {
283
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
284
+ return INT2FIX(xmlTextReaderClose(xreader));
285
+ }
286
+
287
+ /*
288
+ * call-seq:
289
+ * reader.move_to_attribute_no(index) -> code
290
+ *
291
+ * Move the position of the current instance to the attribute with the
292
+ * specified index relative to the containing element.
293
+ */
294
+ static VALUE rxml_reader_move_to_attr_no(VALUE self, VALUE index)
295
+ {
296
+ int ret;
297
+ xmlTextReaderPtr xreader;
298
+
299
+ xreader = rxml_text_reader_get(self);
300
+ ret = xmlTextReaderMoveToAttributeNo(xreader, FIX2INT(index));
301
+
302
+ return INT2FIX(ret);
303
+ }
304
+
305
+ /*
306
+ * call-seq:
307
+ * reader.move_to_attribute(localName) -> code
308
+ *
309
+ * Move the position of the current instance to the attribute with the
310
+ * specified name relative to the containing element.
311
+ */
312
+ static VALUE rxml_reader_move_to_attr(VALUE self, VALUE val)
313
+ {
314
+ int ret;
315
+ xmlTextReaderPtr xreader;
316
+
317
+ xreader = rxml_text_reader_get(self);
318
+ ret = xmlTextReaderMoveToAttribute(xreader,
319
+ (const xmlChar *) StringValueCStr(val));
320
+
321
+ return INT2FIX(ret);
322
+ }
323
+
324
+ /*
325
+ * call-seq:
326
+ * reader.move_to_attribute_ns(localName, namespaceURI) -> code
327
+ *
328
+ * Move the position of the current instance to the attribute with the
329
+ * specified name and namespace relative to the containing element.
330
+ */
331
+ static VALUE rxml_reader_move_to_attr_ns(VALUE self, VALUE name, VALUE ns)
332
+ {
333
+ int ret;
334
+ xmlTextReaderPtr xreader;
335
+
336
+ xreader = rxml_text_reader_get(self);
337
+ ret = xmlTextReaderMoveToAttributeNs(xreader,
338
+ (const xmlChar *) StringValueCStr(name),
339
+ (const xmlChar *) StringValueCStr(ns));
340
+
341
+ return INT2FIX(ret);
342
+ }
343
+
344
+ /*
345
+ * call-seq:
346
+ * reader.move_to_first_attribute -> code
347
+ *
348
+ * Move the position of the current instance to the first attribute associated
349
+ * with the current node.
350
+ */
351
+ static VALUE rxml_reader_move_to_first_attr(VALUE self)
352
+ {
353
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
354
+ return INT2FIX(xmlTextReaderMoveToFirstAttribute(xreader));
355
+ }
356
+
357
+ /*
358
+ * call-seq:
359
+ * reader.move_to_next_attribute -> code
360
+ *
361
+ * Move the position of the current instance to the next attribute associated
362
+ * with the current node.
363
+ */
364
+ static VALUE rxml_reader_move_to_next_attr(VALUE self)
365
+ {
366
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
367
+ return INT2FIX(xmlTextReaderMoveToNextAttribute(xreader));
368
+ }
369
+
370
+ /*
371
+ * call-seq:
372
+ * reader.move_to_element -> code
373
+ *
374
+ * Move the position of the current instance to the node that contains the
375
+ * current attribute node.
376
+ */
377
+ static VALUE rxml_reader_move_to_element(VALUE self)
378
+ {
379
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
380
+ return INT2FIX(xmlTextReaderMoveToElement(xreader));
381
+ }
382
+
383
+ /*
384
+ * call-seq:
385
+ * reader.next -> code
386
+ *
387
+ * Skip to the node following the current one in document order while avoiding
388
+ * the subtree if any.
389
+ */
390
+ static VALUE rxml_reader_next(VALUE self)
391
+ {
392
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
393
+ return INT2FIX(xmlTextReaderNext(xreader));
394
+ }
395
+
396
+ /*
397
+ * call-seq:
398
+ * reader.next_sibling -> code
399
+ *
400
+ * Skip to the node following the current one in document order while avoiding
401
+ * the subtree if any. Currently implemented only for Readers built on a
402
+ * document.
403
+ */
404
+ static VALUE rxml_reader_next_sibling(VALUE self)
405
+ {
406
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
407
+ return INT2FIX(xmlTextReaderNextSibling(xreader));
408
+ }
409
+
410
+ /*
411
+ * call-seq:
412
+ * reader.node -> XML::Node
413
+ *
414
+ * Returns the reader's current node. It will return
415
+ * nil if Reader#read has not yet been called.
416
+ * WARNING - Using this method is dangerous because the
417
+ * the node may be destroyed on the next #read.
418
+ */
419
+ static VALUE rxml_reader_node(VALUE self)
420
+ {
421
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
422
+ xmlNodePtr xnode = xmlTextReaderCurrentNode(xreader);
423
+ return xnode ? rxml_node_wrap(xnode) : Qnil;
424
+ }
425
+
426
+ /*
427
+ * call-seq:
428
+ * reader.node_type -> type
429
+ *
430
+ * Get the node type of the current node. Reference:
431
+ * http://dotgnu.org/pnetlib-doc/System/Xml/XmlNodeType.html
432
+ */
433
+ static VALUE rxml_reader_node_type(VALUE self)
434
+ {
435
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
436
+ return INT2FIX(xmlTextReaderNodeType(xreader));
437
+ }
438
+
439
+ /*
440
+ * call-seq:
441
+ * reader.normalization -> value
442
+ *
443
+ * The value indicating whether to normalize white space and attribute values.
444
+ * Since attribute value and end of line normalizations are a MUST in the XML
445
+ * specification only the value true is accepted. The broken bahaviour of
446
+ * accepting out of range character entities like &#0; is of course not
447
+ * supported either.
448
+ *
449
+ * Return 1 or -1 in case of error.
450
+ */
451
+ static VALUE rxml_reader_normalization(VALUE self)
452
+ {
453
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
454
+ return INT2FIX(xmlTextReaderNormalization(xreader));
455
+ }
456
+
457
+ /*
458
+ * call-seq:
459
+ * reader.read -> nil|true|false
460
+ *
461
+ * Causes the reader to move to the next node in the stream, exposing its properties.
462
+ *
463
+ * Returns true if a node was successfully read or false if there are no more
464
+ * nodes to read. On errors, an exception is raised.*/
465
+ static VALUE rxml_reader_read(VALUE self)
466
+ {
467
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
468
+ int result = xmlTextReaderRead(xreader);
469
+ switch(result)
470
+ {
471
+ case -1:
472
+ rxml_raise(&xmlLastError);
473
+ return Qnil;
474
+ break;
475
+ case 0:
476
+ return Qfalse;
477
+ case 1:
478
+ return Qtrue;
479
+ default:
480
+ rb_raise(rb_eRuntimeError,
481
+ "xmlTextReaderRead did not return -1, 0 or 1. Return value was: %d", result);
482
+ }
483
+ }
484
+
485
+ /*
486
+ * call-seq:
487
+ * reader.read_attribute_value -> code
488
+ *
489
+ * Parse an attribute value into one or more Text and EntityReference nodes.
490
+ *
491
+ * Return 1 in case of success, 0 if the reader was not positionned on an
492
+ * attribute node or all the attribute values have been read, or -1 in case of
493
+ * error.
494
+ */
495
+ static VALUE rxml_reader_read_attr_value(VALUE self)
496
+ {
497
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
498
+ return INT2FIX(xmlTextReaderReadAttributeValue(xreader));
499
+ }
500
+
501
+ /*
502
+ * call-seq:
503
+ * reader.read_inner_xml -> data
504
+ *
505
+ * Read the contents of the current node, including child nodes and markup.
506
+ *
507
+ * Return a string containing the XML content, or nil if the current node is
508
+ * neither an element nor attribute, or has no child nodes.
509
+ */
510
+ static VALUE rxml_reader_read_inner_xml(VALUE self)
511
+ {
512
+ VALUE result = Qnil;
513
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
514
+
515
+ xmlChar *xml = xmlTextReaderReadInnerXml(xReader);
516
+
517
+ if (xml)
518
+ {
519
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
520
+ result = rxml_new_cstr( xml, xencoding);
521
+ xmlFree(xml);
522
+ }
523
+
524
+ return result;
525
+ }
526
+
527
+ /*
528
+ * call-seq:
529
+ * reader.read_outer_xml -> data
530
+ *
531
+ * Read the contents of the current node, including child nodes and markup.
532
+ *
533
+ * Return a string containing the XML content, or nil if the current node is
534
+ * neither an element nor attribute, or has no child nodes.
535
+ */
536
+ static VALUE rxml_reader_read_outer_xml(VALUE self)
537
+ {
538
+ VALUE result = Qnil;
539
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
540
+
541
+ xmlChar *xml = xmlTextReaderReadOuterXml(xReader);
542
+
543
+ if (xml)
544
+ {
545
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
546
+ result = rxml_new_cstr( xml, xencoding);
547
+ xmlFree(xml);
548
+ }
549
+
550
+ return result;
551
+ }
552
+
553
+ /*
554
+ * call-seq:
555
+ * reader.read_state -> state
556
+ *
557
+ * Get the read state of the reader.
558
+ */
559
+ static VALUE rxml_reader_read_state(VALUE self)
560
+ {
561
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
562
+ return INT2FIX(xmlTextReaderReadState(xreader));
563
+ }
564
+
565
+ /*
566
+ * call-seq:
567
+ * reader.read_string -> string
568
+ *
569
+ * Read the contents of an element or a text node as a string.
570
+ *
571
+ * Return a string containing the contents of the Element or Text node, or nil
572
+ * if the reader is positioned on any other type of node.
573
+ */
574
+ static VALUE rxml_reader_read_string(VALUE self)
575
+ {
576
+ VALUE result = Qnil;
577
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
578
+
579
+ xmlChar *xml = xmlTextReaderReadString(xReader);
580
+
581
+ if (xml)
582
+ {
583
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
584
+ result = rxml_new_cstr( xml, xencoding);
585
+ xmlFree(xml);
586
+ }
587
+
588
+ return result;
589
+ }
590
+
591
+ /*
592
+ * call-seq:
593
+ * reader.relax_ng_validate(rng) -> boolean
594
+ *
595
+ * Use RelaxNG to validate the document as it is processed. Activation is only
596
+ * possible before the first read. If +rng+ is nil, the RelaxNG validation is
597
+ * desactivated.
598
+ *
599
+ * Return true in case the RelaxNG validation could be (des)activated and false in
600
+ * case of error.
601
+ */
602
+ static VALUE rxml_reader_relax_ng_validate(VALUE self, VALUE rng)
603
+ {
604
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
605
+ xmlRelaxNGPtr xrelax;
606
+ int status;
607
+ Data_Get_Struct(rng, xmlRelaxNG, xrelax);
608
+
609
+ status = xmlTextReaderRelaxNGSetSchema(xreader, xrelax);
610
+ return (status == 0 ? Qtrue : Qfalse);
611
+ }
612
+
613
+ #if LIBXML_VERSION >= 20620
614
+ /*
615
+ * call-seq:
616
+ * reader.schema_validate(schema) -> boolean
617
+ *
618
+ * Use W3C XSD schema to validate the document as it is processed. Activation
619
+ * is only possible before the first read. If +schema+ is nil, then XML Schema
620
+ * validation is deactivated.
621
+ *
622
+ * Return false if if the schema's validation could be (de)activated and true
623
+ * otherwise.
624
+ */
625
+ static VALUE
626
+ rxml_reader_schema_validate(VALUE self, VALUE xsd)
627
+ {
628
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
629
+ xmlSchemaPtr xschema;
630
+ int status;
631
+
632
+ Data_Get_Struct(xsd, xmlSchema, xschema);
633
+ status = xmlTextReaderSetSchema(xreader, xschema);
634
+ return (status == 0 ? Qtrue : Qfalse);
635
+ }
636
+ #endif
637
+
638
+ /*
639
+ * call-seq:
640
+ * reader.name -> name
641
+ *
642
+ * Return the qualified name of the node.
643
+ */
644
+ static VALUE rxml_reader_name(VALUE self)
645
+ {
646
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
647
+ const xmlChar *result = xmlTextReaderConstName(xReader);
648
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
649
+
650
+ return (result == NULL ? Qnil : rxml_new_cstr(result, xencoding));
651
+ }
652
+
653
+ /*
654
+ * call-seq:
655
+ * reader.local_name -> name
656
+ *
657
+ * Return the local name of the node.
658
+ */
659
+ static VALUE rxml_reader_local_name(VALUE self)
660
+ {
661
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
662
+ const xmlChar *result = xmlTextReaderConstLocalName(xReader);
663
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
664
+
665
+ return (result == NULL ? Qnil : rxml_new_cstr(result, xencoding));
666
+ }
667
+
668
+ /*
669
+ * call-seq:
670
+ * reader.attribute_count -> count
671
+ *
672
+ * Provide the number of attributes of the current node.
673
+ */
674
+ static VALUE rxml_reader_attr_count(VALUE self)
675
+ {
676
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
677
+ return INT2FIX(xmlTextReaderAttributeCount(xreader));
678
+ }
679
+
680
+ /*
681
+ * call-seq:
682
+ * reader.encoding -> XML::Encoding::UTF_8
683
+ *
684
+ * Returns the encoding of the document being read. Note you
685
+ * first have to read data from the reader for encoding
686
+ * to return a value
687
+ *
688
+ * reader = XML::Reader.file(XML_FILE)
689
+ * assert_nil(reader.encoding)
690
+ * reader.read
691
+ * assert_equal(XML::Encoding::UTF_8, reader.encoding)
692
+ *
693
+ * In addition, libxml always appears to return nil for the encoding
694
+ * when parsing strings.
695
+ */
696
+ static VALUE rxml_reader_encoding(VALUE self)
697
+ {
698
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
699
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xreader);
700
+ if (xencoding)
701
+ return INT2NUM(xmlParseCharEncoding((const char*)xencoding));
702
+ else
703
+ return INT2NUM(XML_CHAR_ENCODING_NONE);
704
+ }
705
+
706
+ /*
707
+ * call-seq:
708
+ * reader.base_uri -> URI
709
+ *
710
+ * Determine the base URI of the node.
711
+ */
712
+ static VALUE rxml_reader_base_uri(VALUE self)
713
+ {
714
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
715
+ const xmlChar *result = xmlTextReaderConstBaseUri(xReader);
716
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
717
+
718
+ return (result == NULL ? Qnil : rxml_new_cstr(result, xencoding));
719
+ }
720
+
721
+ /*
722
+ * call-seq:
723
+ * reader.namespace_uri -> URI
724
+ *
725
+ * Determine the namespace URI of the node.
726
+ */
727
+ static VALUE rxml_reader_namespace_uri(VALUE self)
728
+ {
729
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
730
+ const xmlChar *result = xmlTextReaderConstNamespaceUri(xReader);
731
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
732
+
733
+ return (result == NULL ? Qnil : rxml_new_cstr(result, xencoding));
734
+ }
735
+
736
+ /*
737
+ * call-seq:
738
+ * reader.value -> text
739
+ *
740
+ * Provide the text value of the node if present.
741
+ */
742
+ static VALUE rxml_reader_value(VALUE self)
743
+ {
744
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
745
+ const xmlChar *result = xmlTextReaderConstValue(xReader);
746
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
747
+
748
+ return (result == NULL ? Qnil : rxml_new_cstr(result, xencoding));
749
+ }
750
+
751
+ /*
752
+ * call-seq:
753
+ * reader.prefix -> prefix
754
+ *
755
+ * Get a shorthand reference to the namespace associated with the node.
756
+ */
757
+ static VALUE rxml_reader_prefix(VALUE self)
758
+ {
759
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
760
+ const xmlChar *result = xmlTextReaderConstPrefix(xReader);
761
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
762
+
763
+ return (result == NULL ? Qnil : rxml_new_cstr(result, xencoding));
764
+ }
765
+
766
+ /*
767
+ * call-seq:
768
+ * reader.depth -> depth
769
+ *
770
+ * Get the depth of the node in the tree.
771
+ */
772
+ static VALUE rxml_reader_depth(VALUE self)
773
+ {
774
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
775
+ return INT2FIX(xmlTextReaderDepth(xreader));
776
+ }
777
+
778
+ /*
779
+ * call-seq:
780
+ * reader.quote_char -> char
781
+ *
782
+ * Get the quotation mark character used to enclose the value of an attribute,
783
+ * as an integer value (and -1 in case of error).
784
+ */
785
+ static VALUE rxml_reader_quote_char(VALUE self)
786
+ {
787
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
788
+ return INT2FIX(xmlTextReaderQuoteChar(xreader));
789
+ }
790
+
791
+ /*
792
+ * call-seq:
793
+ * reader.standalone -> code
794
+ *
795
+ * Determine the standalone status of the document being read.
796
+ *
797
+ * Return 1 if the document was declared to be standalone, 0 if it was
798
+ * declared to be not standalone, or -1 if the document did not specify its
799
+ * standalone status or in case of error.
800
+ */
801
+ static VALUE rxml_reader_standalone(VALUE self)
802
+ {
803
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
804
+ return INT2FIX(xmlTextReaderStandalone(xreader));
805
+ }
806
+
807
+ /*
808
+ * call-seq:
809
+ * reader.xml_lang -> value
810
+ *
811
+ * Get the xml:lang scope within which the node resides.
812
+ */
813
+ static VALUE rxml_reader_xml_lang(VALUE self)
814
+ {
815
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
816
+ const xmlChar *result = xmlTextReaderConstXmlLang(xReader);
817
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
818
+
819
+ return (result == NULL ? Qnil : rxml_new_cstr(result, xencoding));
820
+ }
821
+
822
+ /*
823
+ * call-seq:
824
+ * reader.xml_version -> version
825
+ *
826
+ * Determine the XML version of the document being read.
827
+ */
828
+ static VALUE rxml_reader_xml_version(VALUE self)
829
+ {
830
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
831
+ const xmlChar *result = xmlTextReaderConstXmlVersion(xReader);
832
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
833
+
834
+ return (result == NULL ? Qnil : rxml_new_cstr(result, xencoding));
835
+ }
836
+
837
+ /*
838
+ * call-seq:
839
+ * reader.has_attributes? -> bool
840
+ *
841
+ * Get whether the node has attributes.
842
+ */
843
+ static VALUE rxml_reader_has_attributes(VALUE self)
844
+ {
845
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
846
+ return xmlTextReaderHasAttributes(xreader) ? Qtrue : Qfalse;
847
+ }
848
+
849
+ /*
850
+ * call-seq:
851
+ * reader.has_value? -> bool
852
+ *
853
+ * Get whether the node can have a text value.
854
+ */
855
+ static VALUE rxml_reader_has_value(VALUE self)
856
+ {
857
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
858
+ return xmlTextReaderHasValue(xreader) ? Qtrue : Qfalse;
859
+ }
860
+
861
+ /*
862
+ * call-seq:
863
+ * reader[key] -> value
864
+ *
865
+ * Provide the value of the attribute with the specified index (if +key+ is an
866
+ * integer) or with the specified name (if +key+ is a string) relative to the
867
+ * containing element, as a string.
868
+ */
869
+ static VALUE rxml_reader_attribute(VALUE self, VALUE key)
870
+ {
871
+ VALUE result = Qnil;
872
+ xmlChar *xattr;
873
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
874
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
875
+
876
+ if (TYPE(key) == T_FIXNUM)
877
+ {
878
+ xattr = xmlTextReaderGetAttributeNo(xReader, FIX2INT(key));
879
+ }
880
+ else
881
+ {
882
+ xattr = xmlTextReaderGetAttribute(xReader, (const xmlChar *) StringValueCStr(key));
883
+ }
884
+
885
+ if (xattr)
886
+ {
887
+ result = rxml_new_cstr(xattr, xencoding);
888
+ xmlFree(xattr);
889
+ }
890
+ return result;
891
+ }
892
+
893
+ /*
894
+ * call-seq:
895
+ * reader.get_attribute(localName) -> value
896
+ *
897
+ * Provide the value of the attribute with the specified name
898
+ * relative to the containing element.
899
+ */
900
+ static VALUE rxml_reader_get_attribute(VALUE self, VALUE name)
901
+ {
902
+ VALUE result = Qnil;
903
+ xmlChar *xattr;
904
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
905
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
906
+
907
+ xattr = xmlTextReaderGetAttribute(xReader, (const xmlChar *) StringValueCStr(name));
908
+ if (xattr)
909
+ {
910
+ result = rxml_new_cstr(xattr, xencoding);
911
+ xmlFree(xattr);
912
+ }
913
+ return result;
914
+ }
915
+
916
+ /*
917
+ * call-seq:
918
+ * reader.get_attribute_no(index) -> value
919
+ *
920
+ * Provide the value of the attribute with the specified index
921
+ * relative to the containing element.
922
+ */
923
+ static VALUE rxml_reader_get_attribute_no(VALUE self, VALUE index)
924
+ {
925
+ VALUE result = Qnil;
926
+ xmlChar *xattr;
927
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
928
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
929
+
930
+ xattr = xmlTextReaderGetAttributeNo(xReader, FIX2INT(index));
931
+ if (xattr)
932
+ {
933
+ result = rxml_new_cstr(xattr, xencoding);
934
+ xmlFree(xattr);
935
+ }
936
+ return result;
937
+ }
938
+
939
+ static VALUE rxml_reader_get_attribute_ns(VALUE self, VALUE name, VALUE ns)
940
+ {
941
+ VALUE result = Qnil;
942
+ xmlChar *xattr;
943
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
944
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
945
+
946
+ xattr = xmlTextReaderGetAttributeNs(xReader,
947
+ (const xmlChar *) StringValueCStr(name),
948
+ (const xmlChar *) StringValueCStr(ns));
949
+ if (xattr)
950
+ {
951
+ result = rxml_new_cstr(xattr, xencoding);
952
+ xmlFree(xattr);
953
+ }
954
+ return result;
955
+ }
956
+
957
+ /*
958
+ * call-seq:
959
+ * reader.lookup_namespace(prefix) -> value
960
+ *
961
+ * Resolve a namespace prefix in the scope of the current element.
962
+ * To return the default namespace, specify nil as +prefix+.
963
+ */
964
+ static VALUE rxml_reader_lookup_namespace(VALUE self, VALUE prefix)
965
+ {
966
+ VALUE result = Qnil;
967
+ xmlTextReaderPtr xReader = rxml_text_reader_get(self);
968
+ const xmlChar *xnamespace = xmlTextReaderLookupNamespace(xReader, (const xmlChar *) StringValueCStr(prefix));
969
+ const xmlChar *xencoding = xmlTextReaderConstEncoding(xReader);
970
+
971
+ if (xnamespace)
972
+ {
973
+ result = rxml_new_cstr(xnamespace, xencoding);
974
+ xmlFree((void *)xnamespace);
975
+ }
976
+ return result;
977
+ }
978
+
979
+ /*
980
+ * call-seq:
981
+ * reader.expand -> node
982
+ *
983
+ * Returns the current node and its full subtree. Note the returned node
984
+ * is valid ONLY until the next read call. If you would like to preserve
985
+ * the node, or search it via xpath, call reader.doc first.
986
+ */
987
+ static VALUE rxml_reader_expand(VALUE self)
988
+ {
989
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
990
+ xmlNodePtr xnode = xmlTextReaderExpand(xreader);
991
+
992
+ if (!xnode)
993
+ {
994
+ return Qnil;
995
+ }
996
+ else
997
+ {
998
+ /* We cannot call rxml_node_wrap here because its sets up a mark function
999
+ for the node. But according to the libxml docs (http://xmlsoft.org/html/libxml-xmlreader.html#xmlTextReaderExpand)
1000
+ this is only valid until the next xmlTextReaderRead call. At that point the node is freed (from reading
1001
+ the libxml2 source code. So don't set a mark or free function, because they will get called in the next
1002
+ garbage collection run and cause a segfault.*/
1003
+ return Data_Wrap_Struct(cXMLNode, NULL, NULL, xnode);
1004
+ }
1005
+ }
1006
+
1007
+ /*
1008
+ * call-seq:
1009
+ * reader.document -> doc
1010
+ *
1011
+ * Hacking interface that provides access to the current document being accessed by the
1012
+ * reader. NOTE: as a result of this call, the reader will not destroy the associated XML
1013
+ * document. Instead, it will be destroyed when the returned document goes out of scope.
1014
+ *
1015
+ * Returns: document
1016
+ */
1017
+ static VALUE rxml_reader_doc(VALUE self)
1018
+ {
1019
+ VALUE result = Qnil;
1020
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
1021
+ xmlDocPtr xdoc = xmlTextReaderCurrentDoc(xreader);
1022
+
1023
+ if (!xdoc)
1024
+ rb_raise(rb_eRuntimeError, "The reader does not have a document. Did you forget to call read?");
1025
+
1026
+ result = rxml_document_wrap(xdoc);
1027
+
1028
+ // And now hook in a mark function to keep the document alive as long as the reader is valid
1029
+ RDATA(self)->dmark = (RUBY_DATA_FUNC)rxml_reader_mark;
1030
+
1031
+ return result;
1032
+ }
1033
+
1034
+
1035
+
1036
+ #if LIBXML_VERSION >= 20618
1037
+ /*
1038
+ * call-seq:
1039
+ * reader.byte_consumed -> value
1040
+ *
1041
+ * This method provides the current index of the parser used by the reader,
1042
+ * relative to the start of the current entity.
1043
+ */
1044
+ static VALUE
1045
+ rxml_reader_byte_consumed(VALUE self)
1046
+ {
1047
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
1048
+ return INT2NUM(xmlTextReaderByteConsumed(xreader));
1049
+ }
1050
+ #endif
1051
+
1052
+ #if LIBXML_VERSION >= 20617
1053
+ /*
1054
+ * call-seq:
1055
+ * reader.column_number -> number
1056
+ *
1057
+ * Provide the column number of the current parsing point.
1058
+ */
1059
+ static VALUE
1060
+ rxml_reader_column_number(VALUE self)
1061
+ {
1062
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
1063
+ return INT2NUM(xmlTextReaderGetParserColumnNumber(xreader));
1064
+ }
1065
+
1066
+ /*
1067
+ * call-seq:
1068
+ * reader.line_number -> number
1069
+ *
1070
+ * Provide the line number of the current parsing point.
1071
+ */
1072
+ static VALUE
1073
+ rxml_reader_line_number(VALUE self)
1074
+ {
1075
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
1076
+ return INT2NUM(xmlTextReaderGetParserLineNumber(xreader));
1077
+ }
1078
+ #endif
1079
+
1080
+ /*
1081
+ * call-seq:
1082
+ * reader.default? -> bool
1083
+ *
1084
+ * Return whether an Attribute node was generated from the default value
1085
+ * defined in the DTD or schema.
1086
+ */
1087
+ static VALUE rxml_reader_default(VALUE self)
1088
+ {
1089
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
1090
+ return xmlTextReaderIsDefault(xreader) ? Qtrue : Qfalse;
1091
+ }
1092
+
1093
+ /*
1094
+ * call-seq:
1095
+ * reader.namespace_declaration? -> bool
1096
+ *
1097
+ * Determine whether the current node is a namespace declaration rather than a
1098
+ * regular attribute.
1099
+ */
1100
+ static VALUE rxml_reader_namespace_declaration(VALUE self)
1101
+ {
1102
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
1103
+ return xmlTextReaderIsNamespaceDecl(xreader) ? Qtrue : Qfalse;
1104
+ }
1105
+
1106
+ /*
1107
+ * call-seq:
1108
+ * reader.empty_element? -> bool
1109
+ *
1110
+ * Check if the current node is empty.
1111
+ */
1112
+ static VALUE rxml_reader_empty_element(VALUE self)
1113
+ {
1114
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
1115
+ return xmlTextReaderIsEmptyElement(xreader) ? Qtrue : Qfalse;
1116
+ }
1117
+
1118
+ /*
1119
+ * call-seq:
1120
+ * reader.valid? -> bool
1121
+ *
1122
+ * Retrieve the validity status from the parser context.
1123
+ */
1124
+ static VALUE rxml_reader_valid(VALUE self)
1125
+ {
1126
+ xmlTextReaderPtr xreader = rxml_text_reader_get(self);
1127
+ return xmlTextReaderIsValid(xreader) ? Qtrue : Qfalse;
1128
+ }
1129
+
1130
+ void rxml_init_reader(void)
1131
+ {
1132
+ BASE_URI_SYMBOL = ID2SYM(rb_intern("base_uri"));
1133
+ ENCODING_SYMBOL = ID2SYM(rb_intern("encoding"));
1134
+ IO_ATTR = rb_intern("@io");
1135
+ OPTIONS_SYMBOL = ID2SYM(rb_intern("options"));
1136
+
1137
+ cXMLReader = rb_define_class_under(mXML, "Reader", rb_cObject);
1138
+
1139
+ rb_define_singleton_method(cXMLReader, "document", rxml_reader_document, 1);
1140
+ rb_define_singleton_method(cXMLReader, "file", rxml_reader_file, -1);
1141
+ rb_define_singleton_method(cXMLReader, "io", rxml_reader_io, -1);
1142
+ rb_define_singleton_method(cXMLReader, "string", rxml_reader_string, -1);
1143
+
1144
+ rb_define_method(cXMLReader, "[]", rxml_reader_attribute, 1);
1145
+ rb_define_method(cXMLReader, "attribute_count", rxml_reader_attr_count, 0);
1146
+ rb_define_method(cXMLReader, "base_uri", rxml_reader_base_uri, 0);
1147
+ #if LIBXML_VERSION >= 20618
1148
+ rb_define_method(cXMLReader, "byte_consumed", rxml_reader_byte_consumed, 0);
1149
+ #endif
1150
+ rb_define_method(cXMLReader, "close", rxml_reader_close, 0);
1151
+ #if LIBXML_VERSION >= 20617
1152
+ rb_define_method(cXMLReader, "column_number", rxml_reader_column_number, 0);
1153
+ #endif
1154
+ rb_define_method(cXMLReader, "depth", rxml_reader_depth, 0);
1155
+ rb_define_method(cXMLReader, "doc", rxml_reader_doc, 0);
1156
+ rb_define_method(cXMLReader, "encoding", rxml_reader_encoding, 0);
1157
+ rb_define_method(cXMLReader, "expand", rxml_reader_expand, 0);
1158
+ rb_define_method(cXMLReader, "get_attribute", rxml_reader_get_attribute, 1);
1159
+ rb_define_method(cXMLReader, "get_attribute_no", rxml_reader_get_attribute_no, 1);
1160
+ rb_define_method(cXMLReader, "get_attribute_ns", rxml_reader_get_attribute_ns, 2);
1161
+ rb_define_method(cXMLReader, "has_attributes?", rxml_reader_has_attributes, 0);
1162
+ rb_define_method(cXMLReader, "has_value?", rxml_reader_has_value, 0);
1163
+ #if LIBXML_VERSION >= 20617
1164
+ rb_define_method(cXMLReader, "line_number", rxml_reader_line_number, 0);
1165
+ #endif
1166
+ rb_define_method(cXMLReader, "local_name", rxml_reader_local_name, 0);
1167
+ rb_define_method(cXMLReader, "lookup_namespace", rxml_reader_lookup_namespace, 1);
1168
+ rb_define_method(cXMLReader, "move_to_attribute", rxml_reader_move_to_attr, 1);
1169
+ rb_define_method(cXMLReader, "move_to_attribute_no", rxml_reader_move_to_attr_no, 1);
1170
+ rb_define_method(cXMLReader, "move_to_attribute_ns", rxml_reader_move_to_attr_ns, 2);
1171
+ rb_define_method(cXMLReader, "move_to_first_attribute", rxml_reader_move_to_first_attr, 0);
1172
+ rb_define_method(cXMLReader, "move_to_next_attribute", rxml_reader_move_to_next_attr, 0);
1173
+ rb_define_method(cXMLReader, "move_to_element", rxml_reader_move_to_element, 0);
1174
+ rb_define_method(cXMLReader, "name", rxml_reader_name, 0);
1175
+ rb_define_method(cXMLReader, "namespace_uri", rxml_reader_namespace_uri, 0);
1176
+ rb_define_method(cXMLReader, "next", rxml_reader_next, 0);
1177
+ rb_define_method(cXMLReader, "next_sibling", rxml_reader_next_sibling, 0);
1178
+ rb_define_method(cXMLReader, "node", rxml_reader_node, 0);
1179
+ rb_define_method(cXMLReader, "node_type", rxml_reader_node_type, 0);
1180
+ rb_define_method(cXMLReader, "normalization", rxml_reader_normalization, 0);
1181
+ rb_define_method(cXMLReader, "prefix", rxml_reader_prefix, 0);
1182
+ rb_define_method(cXMLReader, "quote_char", rxml_reader_quote_char, 0);
1183
+ rb_define_method(cXMLReader, "read", rxml_reader_read, 0);
1184
+ rb_define_method(cXMLReader, "read_attribute_value", rxml_reader_read_attr_value, 0);
1185
+ rb_define_method(cXMLReader, "read_inner_xml", rxml_reader_read_inner_xml, 0);
1186
+ rb_define_method(cXMLReader, "read_outer_xml", rxml_reader_read_outer_xml, 0);
1187
+ rb_define_method(cXMLReader, "read_state", rxml_reader_read_state, 0);
1188
+ rb_define_method(cXMLReader, "read_string", rxml_reader_read_string, 0);
1189
+ rb_define_method(cXMLReader, "relax_ng_validate", rxml_reader_relax_ng_validate, 1);
1190
+ rb_define_method(cXMLReader, "standalone", rxml_reader_standalone, 0);
1191
+ #if LIBXML_VERSION >= 20620
1192
+ rb_define_method(cXMLReader, "schema_validate", rxml_reader_schema_validate, 1);
1193
+ #endif
1194
+ rb_define_method(cXMLReader, "value", rxml_reader_value, 0);
1195
+ rb_define_method(cXMLReader, "xml_lang", rxml_reader_xml_lang, 0);
1196
+ rb_define_method(cXMLReader, "xml_version", rxml_reader_xml_version, 0);
1197
+ rb_define_method(cXMLReader, "default?", rxml_reader_default, 0);
1198
+ rb_define_method(cXMLReader, "empty_element?", rxml_reader_empty_element, 0);
1199
+ rb_define_method(cXMLReader, "namespace_declaration?", rxml_reader_namespace_declaration, 0);
1200
+ rb_define_method(cXMLReader, "valid?", rxml_reader_valid, 0);
1201
+
1202
+ /* Constants */
1203
+ rb_define_const(cXMLReader, "LOADDTD", INT2FIX(XML_PARSER_LOADDTD));
1204
+ rb_define_const(cXMLReader, "DEFAULTATTRS", INT2FIX(XML_PARSER_DEFAULTATTRS));
1205
+ rb_define_const(cXMLReader, "VALIDATE", INT2FIX(XML_PARSER_VALIDATE));
1206
+ rb_define_const(cXMLReader, "SUBST_ENTITIES", INT2FIX(XML_PARSER_SUBST_ENTITIES));
1207
+
1208
+ rb_define_const(cXMLReader, "SEVERITY_VALIDITY_WARNING", INT2FIX(XML_PARSER_SEVERITY_VALIDITY_WARNING));
1209
+ rb_define_const(cXMLReader, "SEVERITY_VALIDITY_ERROR", INT2FIX(XML_PARSER_SEVERITY_VALIDITY_ERROR));
1210
+ rb_define_const(cXMLReader, "SEVERITY_WARNING", INT2FIX(XML_PARSER_SEVERITY_WARNING));
1211
+ rb_define_const(cXMLReader, "SEVERITY_ERROR", INT2FIX(XML_PARSER_SEVERITY_ERROR));
1212
+
1213
+ rb_define_const(cXMLReader, "TYPE_NONE", INT2FIX(XML_READER_TYPE_NONE));
1214
+ rb_define_const(cXMLReader, "TYPE_ELEMENT", INT2FIX(XML_READER_TYPE_ELEMENT));
1215
+ rb_define_const(cXMLReader, "TYPE_ATTRIBUTE", INT2FIX(XML_READER_TYPE_ATTRIBUTE));
1216
+ rb_define_const(cXMLReader, "TYPE_TEXT", INT2FIX(XML_READER_TYPE_TEXT));
1217
+ rb_define_const(cXMLReader, "TYPE_CDATA", INT2FIX(XML_READER_TYPE_CDATA));
1218
+ rb_define_const(cXMLReader, "TYPE_ENTITY_REFERENCE", INT2FIX(XML_READER_TYPE_ENTITY_REFERENCE));
1219
+ rb_define_const(cXMLReader, "TYPE_ENTITY", INT2FIX(XML_READER_TYPE_ENTITY));
1220
+ rb_define_const(cXMLReader, "TYPE_PROCESSING_INSTRUCTION", INT2FIX(XML_READER_TYPE_PROCESSING_INSTRUCTION));
1221
+ rb_define_const(cXMLReader, "TYPE_COMMENT", INT2FIX(XML_READER_TYPE_COMMENT));
1222
+ rb_define_const(cXMLReader, "TYPE_DOCUMENT", INT2FIX(XML_READER_TYPE_DOCUMENT));
1223
+ rb_define_const(cXMLReader, "TYPE_DOCUMENT_TYPE", INT2FIX(XML_READER_TYPE_DOCUMENT_TYPE));
1224
+ rb_define_const(cXMLReader, "TYPE_DOCUMENT_FRAGMENT", INT2FIX(XML_READER_TYPE_DOCUMENT_FRAGMENT));
1225
+ rb_define_const(cXMLReader, "TYPE_NOTATION", INT2FIX(XML_READER_TYPE_NOTATION));
1226
+ rb_define_const(cXMLReader, "TYPE_WHITESPACE", INT2FIX(XML_READER_TYPE_WHITESPACE));
1227
+ rb_define_const(cXMLReader, "TYPE_SIGNIFICANT_WHITESPACE", INT2FIX(XML_READER_TYPE_SIGNIFICANT_WHITESPACE));
1228
+ rb_define_const(cXMLReader, "TYPE_END_ELEMENT", INT2FIX(XML_READER_TYPE_END_ELEMENT));
1229
+ rb_define_const(cXMLReader, "TYPE_END_ENTITY", INT2FIX(XML_READER_TYPE_END_ENTITY));
1230
+ rb_define_const(cXMLReader, "TYPE_XML_DECLARATION", INT2FIX(XML_READER_TYPE_XML_DECLARATION));
1231
+
1232
+ /* Read states */
1233
+ rb_define_const(cXMLReader, "MODE_INITIAL", INT2FIX(XML_TEXTREADER_MODE_INITIAL));
1234
+ rb_define_const(cXMLReader, "MODE_INTERACTIVE", INT2FIX(XML_TEXTREADER_MODE_INTERACTIVE));
1235
+ rb_define_const(cXMLReader, "MODE_ERROR", INT2FIX(XML_TEXTREADER_MODE_ERROR));
1236
+ rb_define_const(cXMLReader, "MODE_EOF", INT2FIX(XML_TEXTREADER_MODE_EOF));
1237
+ rb_define_const(cXMLReader, "MODE_CLOSED", INT2FIX(XML_TEXTREADER_MODE_CLOSED));
1238
+ rb_define_const(cXMLReader, "MODE_READING", INT2FIX(XML_TEXTREADER_MODE_READING));
1239
+ }