libxml-ruby 2.8.0 → 3.2.3

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