libxml-ruby 2.9.0-x64-mingw32

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