libxml-ruby 0.8.3 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. data/CHANGES +18 -0
  2. data/RAKEFILE +15 -39
  3. data/README +48 -47
  4. data/ext/libxml/libxml.c +847 -22
  5. data/ext/libxml/ruby_libxml.h +71 -95
  6. data/ext/libxml/ruby_xml_attr.c +500 -500
  7. data/ext/libxml/ruby_xml_attributes.c +1 -1
  8. data/ext/libxml/ruby_xml_document.c +1144 -1135
  9. data/ext/libxml/ruby_xml_document.h +4 -11
  10. data/ext/libxml/ruby_xml_dtd.c +27 -0
  11. data/ext/libxml/ruby_xml_encoding.c +164 -0
  12. data/ext/libxml/ruby_xml_encoding.h +13 -0
  13. data/ext/libxml/ruby_xml_error.c +941 -0
  14. data/ext/libxml/ruby_xml_error.h +13 -0
  15. data/ext/libxml/ruby_xml_html_parser.c +71 -387
  16. data/ext/libxml/ruby_xml_html_parser.h +1 -17
  17. data/ext/libxml/ruby_xml_input.c +179 -0
  18. data/ext/libxml/ruby_xml_input.h +18 -0
  19. data/ext/libxml/ruby_xml_input_cbg.c +17 -3
  20. data/ext/libxml/ruby_xml_node.c +1566 -1582
  21. data/ext/libxml/ruby_xml_node.h +1 -4
  22. data/ext/libxml/ruby_xml_ns.c +14 -3
  23. data/ext/libxml/ruby_xml_parser.c +164 -1398
  24. data/ext/libxml/ruby_xml_parser.h +5 -17
  25. data/ext/libxml/ruby_xml_parser_context.c +131 -169
  26. data/ext/libxml/ruby_xml_parser_context.h +2 -9
  27. data/ext/libxml/ruby_xml_reader.c +910 -945
  28. data/ext/libxml/ruby_xml_relaxng.c +32 -3
  29. data/ext/libxml/ruby_xml_sax_parser.c +106 -364
  30. data/ext/libxml/ruby_xml_sax_parser.h +1 -37
  31. data/ext/libxml/ruby_xml_schema.c +174 -145
  32. data/ext/libxml/ruby_xml_xinclude.c +9 -5
  33. data/ext/libxml/ruby_xml_xpath.c +25 -6
  34. data/ext/libxml/ruby_xml_xpath.h +1 -2
  35. data/ext/libxml/ruby_xml_xpath_context.c +17 -19
  36. data/ext/libxml/ruby_xml_xpath_object.c +60 -56
  37. data/ext/libxml/ruby_xml_xpointer.c +11 -5
  38. data/ext/libxml/sax_parser_callbacks.inc +42 -37
  39. data/ext/libxml/version.h +3 -3
  40. data/ext/mingw/Rakefile +20 -27
  41. data/ext/mingw/build.rake +41 -0
  42. data/ext/vc/libxml_ruby.vcproj +23 -15
  43. data/lib/libxml.rb +8 -2
  44. data/lib/libxml/document.rb +16 -4
  45. data/lib/libxml/error.rb +84 -0
  46. data/lib/libxml/hpricot.rb +76 -0
  47. data/lib/libxml/html_parser.rb +61 -0
  48. data/lib/libxml/node.rb +36 -25
  49. data/lib/libxml/parser.rb +312 -33
  50. data/lib/libxml/parser_context.rb +17 -0
  51. data/lib/libxml/properties.rb +15 -2
  52. data/lib/libxml/reader.rb +15 -0
  53. data/lib/libxml/sax_callbacks.rb +179 -0
  54. data/lib/libxml/sax_parser.rb +42 -0
  55. data/lib/libxml/tree.rb +1 -2
  56. data/lib/libxml/xpath_object.rb +12 -0
  57. data/test/model/atom.xml +4 -0
  58. data/test/tc_attributes.rb +43 -19
  59. data/test/tc_document.rb +1 -1
  60. data/test/tc_document_write.rb +15 -8
  61. data/test/tc_dtd.rb +36 -20
  62. data/test/tc_encoding.rb +13 -0
  63. data/test/tc_error.rb +136 -0
  64. data/test/tc_node.rb +2 -3
  65. data/test/tc_node_copy.rb +1 -1
  66. data/test/tc_node_edit.rb +6 -0
  67. data/test/tc_ns.rb +18 -0
  68. data/test/tc_parser.rb +113 -228
  69. data/test/tc_parser_context.rb +1 -2
  70. data/test/tc_reader.rb +24 -14
  71. data/test/tc_relaxng.rb +18 -6
  72. data/test/tc_sax_parser.rb +48 -13
  73. data/test/tc_schema.rb +20 -8
  74. data/test/tc_well_formed.rb +2 -1
  75. data/test/tc_xml.rb +212 -0
  76. data/test/tc_xpath.rb +60 -46
  77. data/test/tc_xpointer.rb +7 -11
  78. data/test/test_suite.rb +4 -3
  79. metadata +26 -109
  80. data/doc/rdoc/classes/LibXML.html +0 -241
  81. data/doc/rdoc/classes/LibXML/XML.html +0 -185
  82. data/doc/rdoc/classes/LibXML/XML/Attr.html +0 -1010
  83. data/doc/rdoc/classes/LibXML/XML/Attributes.html +0 -526
  84. data/doc/rdoc/classes/LibXML/XML/Document.html +0 -1489
  85. data/doc/rdoc/classes/LibXML/XML/Dtd.html +0 -213
  86. data/doc/rdoc/classes/LibXML/XML/Error.html +0 -117
  87. data/doc/rdoc/classes/LibXML/XML/HTMLParser.html +0 -348
  88. data/doc/rdoc/classes/LibXML/XML/InputCallbacks.html +0 -160
  89. data/doc/rdoc/classes/LibXML/XML/NS.html +0 -381
  90. data/doc/rdoc/classes/LibXML/XML/Node.html +0 -3396
  91. data/doc/rdoc/classes/LibXML/XML/Node/FailedModify.html +0 -123
  92. data/doc/rdoc/classes/LibXML/XML/Node/Set.html +0 -440
  93. data/doc/rdoc/classes/LibXML/XML/Node/SetNamespace.html +0 -123
  94. data/doc/rdoc/classes/LibXML/XML/Node/UnknownType.html +0 -123
  95. data/doc/rdoc/classes/LibXML/XML/Parser.html +0 -2239
  96. data/doc/rdoc/classes/LibXML/XML/Parser/Context.html +0 -1255
  97. data/doc/rdoc/classes/LibXML/XML/Parser/ParseError.html +0 -123
  98. data/doc/rdoc/classes/LibXML/XML/Reader.html +0 -2264
  99. data/doc/rdoc/classes/LibXML/XML/RelaxNG.html +0 -237
  100. data/doc/rdoc/classes/LibXML/XML/SaxParser.html +0 -415
  101. data/doc/rdoc/classes/LibXML/XML/Schema.html +0 -308
  102. data/doc/rdoc/classes/LibXML/XML/State.html +0 -124
  103. data/doc/rdoc/classes/LibXML/XML/Tree.html +0 -111
  104. data/doc/rdoc/classes/LibXML/XML/XInclude.html +0 -123
  105. data/doc/rdoc/classes/LibXML/XML/XInclude/Error.html +0 -117
  106. data/doc/rdoc/classes/LibXML/XML/XMLParserOptions.html +0 -198
  107. data/doc/rdoc/classes/LibXML/XML/XPath.html +0 -184
  108. data/doc/rdoc/classes/LibXML/XML/XPath/Context.html +0 -404
  109. data/doc/rdoc/classes/LibXML/XML/XPath/InvalidPath.html +0 -172
  110. data/doc/rdoc/classes/LibXML/XML/XPath/Object.html +0 -627
  111. data/doc/rdoc/classes/LibXML/XML/XPointer.html +0 -170
  112. data/doc/rdoc/classes/LibXML/XML/XPointer/Context.html +0 -123
  113. data/doc/rdoc/classes/LibXML/XML/XPointer/Context/InvalidPath.html +0 -117
  114. data/doc/rdoc/classes/LibXML/XML/XPointer/InvalidExpression.html +0 -124
  115. data/doc/rdoc/classes/singleton.html +0 -114
  116. data/doc/rdoc/created.rid +0 -1
  117. data/doc/rdoc/files/CHANGES.html +0 -442
  118. data/doc/rdoc/files/LICENSE.html +0 -133
  119. data/doc/rdoc/files/README.html +0 -388
  120. data/doc/rdoc/files/VERSION.html +0 -107
  121. data/doc/rdoc/files/ext/libxml/cbg_c.html +0 -101
  122. data/doc/rdoc/files/ext/libxml/libxml_c.html +0 -101
  123. data/doc/rdoc/files/ext/libxml/ruby_xml_attr_c.html +0 -101
  124. data/doc/rdoc/files/ext/libxml/ruby_xml_attributes_c.html +0 -101
  125. data/doc/rdoc/files/ext/libxml/ruby_xml_document_c.html +0 -101
  126. data/doc/rdoc/files/ext/libxml/ruby_xml_dtd_c.html +0 -101
  127. data/doc/rdoc/files/ext/libxml/ruby_xml_html_parser_c.html +0 -101
  128. data/doc/rdoc/files/ext/libxml/ruby_xml_input_cbg_c.html +0 -101
  129. data/doc/rdoc/files/ext/libxml/ruby_xml_node_c.html +0 -101
  130. data/doc/rdoc/files/ext/libxml/ruby_xml_node_set_c.html +0 -101
  131. data/doc/rdoc/files/ext/libxml/ruby_xml_ns_c.html +0 -101
  132. data/doc/rdoc/files/ext/libxml/ruby_xml_parser_c.html +0 -101
  133. data/doc/rdoc/files/ext/libxml/ruby_xml_parser_context_c.html +0 -101
  134. data/doc/rdoc/files/ext/libxml/ruby_xml_reader_c.html +0 -101
  135. data/doc/rdoc/files/ext/libxml/ruby_xml_relaxng_c.html +0 -101
  136. data/doc/rdoc/files/ext/libxml/ruby_xml_sax_parser_c.html +0 -101
  137. data/doc/rdoc/files/ext/libxml/ruby_xml_schema_c.html +0 -101
  138. data/doc/rdoc/files/ext/libxml/ruby_xml_state_c.html +0 -101
  139. data/doc/rdoc/files/ext/libxml/ruby_xml_xinclude_c.html +0 -101
  140. data/doc/rdoc/files/ext/libxml/ruby_xml_xpath_c.html +0 -101
  141. data/doc/rdoc/files/ext/libxml/ruby_xml_xpath_context_c.html +0 -101
  142. data/doc/rdoc/files/ext/libxml/ruby_xml_xpath_object_c.html +0 -101
  143. data/doc/rdoc/files/ext/libxml/ruby_xml_xpointer_c.html +0 -101
  144. data/doc/rdoc/files/ext/libxml/ruby_xml_xpointer_context_c.html +0 -101
  145. data/doc/rdoc/files/lib/libxml/attr_rb.html +0 -108
  146. data/doc/rdoc/files/lib/libxml/attributes_rb.html +0 -108
  147. data/doc/rdoc/files/lib/libxml/document_rb.html +0 -108
  148. data/doc/rdoc/files/lib/libxml/node_rb.html +0 -108
  149. data/doc/rdoc/files/lib/libxml/node_set_rb.html +0 -108
  150. data/doc/rdoc/files/lib/libxml/parser_options_rb.html +0 -107
  151. data/doc/rdoc/files/lib/libxml/parser_rb.html +0 -101
  152. data/doc/rdoc/files/lib/libxml/properties_rb.html +0 -108
  153. data/doc/rdoc/files/lib/libxml/tree_rb.html +0 -107
  154. data/doc/rdoc/files/lib/libxml_rb.html +0 -124
  155. data/doc/rdoc/files/lib/xml/libxml_rb.html +0 -124
  156. data/doc/rdoc/files/lib/xml_rb.html +0 -134
  157. data/doc/rdoc/fr_class_index.html +0 -62
  158. data/doc/rdoc/fr_file_index.html +0 -66
  159. data/doc/rdoc/fr_method_index.html +0 -392
  160. data/doc/rdoc/index.html +0 -24
  161. data/doc/rdoc/rdoc-style.css +0 -208
  162. data/ext/libxml/ruby_xml_node_set.c +0 -172
  163. data/ext/libxml/ruby_xml_node_set.h +0 -20
  164. data/ext/libxml/ruby_xml_xpointer_context.c +0 -22
  165. data/ext/libxml/ruby_xml_xpointer_context.h +0 -18
  166. data/lib/libxml/node_set.rb +0 -27
  167. data/test/tc_node_set.rb +0 -24
  168. data/test/tc_node_set2.rb +0 -37
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_parser_context.h 319 2008-07-08 07:40:27Z cfis $ */
1
+ /* $Id: ruby_xml_parser_context.h 545 2008-11-17 05:29:39Z cfis $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -7,14 +7,7 @@
7
7
 
8
8
  extern VALUE cXMLParserContext;
9
9
 
10
- typedef struct ruby_xml_parser_context {
11
- xmlParserCtxtPtr ctxt;
12
- int is_ptr;
13
- } ruby_xml_parser_context;
14
-
15
- void ruby_xml_parser_context_free(ruby_xml_parser_context *ctxt);
16
10
  void ruby_init_xml_parser_context(void);
17
- VALUE ruby_xml_parser_context_new();
18
- VALUE ruby_xml_parser_context_each(VALUE self);
11
+ VALUE ruby_xml_parser_context_wrap(xmlParserCtxtPtr ctxt);
19
12
 
20
13
  #endif
@@ -1,945 +1,910 @@
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
- #define CSTR2RVAL(x) (x == NULL ? Qnil : rb_str_new2((const char *)x))
8
- #define RVAL2CSTR(x) (StringValueCStr(x))
9
-
10
- static inline VALUE
11
- __rb_str_new_and_free(xmlChar *x)
12
- {
13
- if (x != NULL) {
14
- VALUE v = rb_str_new2((const char *)x);
15
- xmlFree(x);
16
- return v;
17
- }
18
- return Qnil;
19
- }
20
-
21
- #define CSTR2RVAL2(x) (__rb_str_new_and_free(x))
22
-
23
- VALUE cXMLReader;
24
- static ID error_handler_block_ivar_id;
25
-
26
- static int
27
- ctxtRead(FILE *f, char * buf, size_t len) {
28
- return(fread(buf, 1, len, f));
29
- }
30
-
31
- static VALUE
32
- ruby_xml_reader_new(VALUE class, xmlTextReaderPtr reader)
33
- {
34
- return Data_Wrap_Struct(class, NULL, xmlFreeTextReader, reader);
35
- }
36
-
37
- static xmlTextReaderPtr
38
- ruby_xml_text_reader_get(VALUE obj)
39
- {
40
- xmlTextReaderPtr ptr;
41
- Data_Get_Struct(obj, xmlTextReader, ptr);
42
- return ptr;
43
- }
44
-
45
- /*
46
- * call-seq:
47
- * XML::Reader.file(path, encoding=nil, options=0) -> reader
48
- *
49
- * Parse an XML file from the filesystem or the network. The parsing flags
50
- * options are a combination of xmlParserOption.
51
- */
52
- static VALUE
53
- ruby_xml_reader_new_file(int argc, VALUE *argv, VALUE self)
54
- {
55
- xmlTextReaderPtr reader;
56
- VALUE path, encoding, options;
57
-
58
- rb_scan_args(argc, argv, "12", &path, &encoding, &options);
59
-
60
- reader = xmlReaderForFile(RVAL2CSTR(path),
61
- NIL_P(encoding) ? NULL : RVAL2CSTR(encoding),
62
- NIL_P(options) ? 0 : FIX2INT(options));
63
- if (reader == NULL)
64
- rb_raise(rb_eRuntimeError,
65
- "cannot create text reader for given XML file at path '%s'",
66
- RVAL2CSTR(path));
67
-
68
- return ruby_xml_reader_new(self, reader);
69
- }
70
-
71
- /*
72
- * call-seq:
73
- * XML::Reader.io(io, url=nil, encoding=nil, options=0) -> reader
74
- *
75
- * Parse an XML file from a file handle. The parsing flags options are
76
- * a combination of xmlParserOption.
77
- */
78
- static VALUE
79
- ruby_xml_reader_new_io(int argc, VALUE *argv, VALUE self)
80
- {
81
- xmlTextReaderPtr reader;
82
- VALUE io, url, encoding, options;
83
- OpenFile *fptr;
84
- FILE *f;
85
-
86
- #ifdef _WIN32
87
- rb_raise(rb_eRuntimeError, "Reading an io stream is not supported on Windows");
88
- #endif
89
-
90
- rb_scan_args(argc, argv, "13", &io, &url, &encoding, &options);
91
-
92
- if (!rb_obj_is_kind_of(io, rb_cIO))
93
- rb_raise(rb_eTypeError, "need an IO object");
94
-
95
- GetOpenFile(io, fptr);
96
- rb_io_check_readable(fptr);
97
- f = GetWriteFile(fptr);
98
-
99
- reader = xmlReaderForIO((xmlInputReadCallback) ctxtRead, NULL, f,
100
- NIL_P(url) ? NULL : RVAL2CSTR(url),
101
- NIL_P(encoding) ? NULL : RVAL2CSTR(encoding),
102
- NIL_P(options) ? 0 : FIX2INT(options));
103
- if (reader == NULL)
104
- rb_raise(rb_eRuntimeError, "cannot create text reader for given stream");
105
-
106
- return ruby_xml_reader_new(self, reader);
107
- }
108
-
109
- /*
110
- * call-seq:
111
- * XML::Reader.walker(doc) -> reader
112
- * XML::Reader.document(doc) -> reader
113
- *
114
- * Create an XML text reader for a preparsed document.
115
- */
116
- VALUE
117
- ruby_xml_reader_new_walker(VALUE self, VALUE doc)
118
- {
119
- ruby_xml_document_t *rxd;
120
- xmlTextReaderPtr reader;
121
-
122
- Data_Get_Struct(doc, ruby_xml_document_t, rxd);
123
-
124
- reader = xmlReaderWalker(rxd->doc);
125
- if (reader == NULL)
126
- rb_raise(rb_eRuntimeError, "cannot create text reader for given document");
127
-
128
- return ruby_xml_reader_new(self, reader);
129
- }
130
-
131
- /*
132
- * call-seq:
133
- * XML::Reader.new(data, url=nil, encoding=nil, options=0) -> reader
134
- * XML::Reader.string(data, url=nil, encoding=nil, options=0) -> reader
135
- *
136
- * Create an XML text reader for an XML in-memory document. The parsing flags
137
- * options are a combination of xmlParserOption.
138
- */
139
- static VALUE
140
- ruby_xml_reader_new_data(int argc, VALUE *argv, VALUE self)
141
- {
142
- xmlTextReaderPtr reader;
143
- VALUE data, url, encoding, options;
144
- char *c_data;
145
-
146
- rb_scan_args(argc, argv, "13", &data, &url, &encoding, &options);
147
-
148
- c_data = RVAL2CSTR(data);
149
- reader = xmlReaderForMemory(c_data,
150
- strlen(c_data),
151
- NIL_P(url) ? NULL : RVAL2CSTR(url),
152
- NIL_P(encoding) ? NULL : RVAL2CSTR(encoding),
153
- NIL_P(options) ? 0 : FIX2INT(options));
154
- if (reader == NULL)
155
- rb_raise(rb_eRuntimeError, "cannot create text reader for given data");
156
-
157
- return ruby_xml_reader_new(self, reader);
158
- }
159
-
160
- /*
161
- * call-seq:
162
- * parser.close -> code
163
- *
164
- * This method releases any resources allocated by the current instance
165
- * changes the state to Closed and close any underlying input.
166
- */
167
- static VALUE
168
- ruby_xml_reader_close(VALUE self)
169
- {
170
- return INT2FIX(xmlTextReaderClose(ruby_xml_text_reader_get(self)));
171
- }
172
-
173
- /*
174
- * call-seq:
175
- * parser.move_to_attribute(val) -> code
176
- *
177
- * Move the position of the current instance to the attribute with the
178
- * specified index (if +val+ is an integer) or name (if +val+ is a string)
179
- * relative to the containing element.
180
- */
181
- static VALUE
182
- ruby_xml_reader_move_to_attr(VALUE self, VALUE val)
183
- {
184
- xmlTextReaderPtr reader;
185
- int ret;
186
-
187
- reader = ruby_xml_text_reader_get(self);
188
-
189
- if (TYPE(val) == T_FIXNUM) {
190
- ret = xmlTextReaderMoveToAttributeNo(reader, FIX2INT(val));
191
- }
192
- else {
193
- ret = xmlTextReaderMoveToAttribute(reader, (const xmlChar *)RVAL2CSTR(val));
194
- }
195
-
196
- return INT2FIX(ret);
197
- }
198
-
199
- /*
200
- * call-seq:
201
- * reader.move_to_first_attribute -> code
202
- *
203
- * Move the position of the current instance to the first attribute associated
204
- * with the current node.
205
- */
206
- static VALUE
207
- ruby_xml_reader_move_to_first_attr(VALUE self)
208
- {
209
- return INT2FIX(xmlTextReaderMoveToFirstAttribute(ruby_xml_text_reader_get(self)));
210
- }
211
-
212
- /*
213
- * call-seq:
214
- * reader.move_to_next_attribute -> code
215
- *
216
- * Move the position of the current instance to the next attribute associated
217
- * with the current node.
218
- */
219
- static VALUE
220
- ruby_xml_reader_move_to_next_attr(VALUE self)
221
- {
222
- return INT2FIX(xmlTextReaderMoveToNextAttribute(ruby_xml_text_reader_get(self)));
223
- }
224
-
225
- /*
226
- * call-seq:
227
- * reader.move_to_element -> code
228
- *
229
- * Move the position of the current instance to the node that contains the
230
- * current attribute node.
231
- */
232
- static VALUE
233
- ruby_xml_reader_move_to_element(VALUE self)
234
- {
235
- return INT2FIX(xmlTextReaderMoveToElement(ruby_xml_text_reader_get(self)));
236
- }
237
-
238
- /*
239
- * call-seq:
240
- * reader.next -> code
241
- *
242
- * Skip to the node following the current one in document order while avoiding
243
- * the subtree if any.
244
- */
245
- static VALUE
246
- ruby_xml_reader_next(VALUE self)
247
- {
248
- return INT2FIX(xmlTextReaderNext(ruby_xml_text_reader_get(self)));
249
- }
250
-
251
- /*
252
- * call-seq:
253
- * reader.next_sibling -> code
254
- *
255
- * Skip to the node following the current one in document order while avoiding
256
- * the subtree if any. Currently implemented only for Readers built on a
257
- * document.
258
- */
259
- static VALUE
260
- ruby_xml_reader_next_sibling(VALUE self)
261
- {
262
- return INT2FIX(xmlTextReaderNextSibling(ruby_xml_text_reader_get(self)));
263
- }
264
-
265
- /*
266
- * call-seq:
267
- * reader.node_type -> type
268
- *
269
- * Get the node type of the current node. Reference:
270
- * http://dotgnu.org/pnetlib-doc/System/Xml/XmlNodeType.html
271
- */
272
- static VALUE
273
- ruby_xml_reader_node_type(VALUE self)
274
- {
275
- return INT2FIX(xmlTextReaderNodeType(ruby_xml_text_reader_get(self)));
276
- }
277
-
278
- /*
279
- * call-seq:
280
- * reader.normalization -> value
281
- *
282
- * The value indicating whether to normalize white space and attribute values.
283
- * Since attribute value and end of line normalizations are a MUST in the XML
284
- * specification only the value true is accepted. The broken bahaviour of
285
- * accepting out of range character entities like � is of course not
286
- * supported either.
287
- *
288
- * Return 1 or -1 in case of error.
289
- */
290
- static VALUE
291
- ruby_xml_reader_normalization(VALUE self)
292
- {
293
- return INT2FIX(xmlTextReaderNormalization(ruby_xml_text_reader_get(self)));
294
- }
295
-
296
- /*
297
- * call-seq:
298
- * reader.read -> code
299
- *
300
- * Move the position of the current instance to the next node in the stream,
301
- * exposing its properties.
302
- *
303
- * Return 1 if the node was read successfully, 0 if there is no more nodes to
304
- * read, or -1 in case of error.
305
- */
306
- static VALUE
307
- ruby_xml_reader_read(VALUE self)
308
- {
309
- return INT2FIX(xmlTextReaderRead(ruby_xml_text_reader_get(self)));
310
- }
311
-
312
- /*
313
- * call-seq:
314
- * reader.read_attribute_value -> code
315
- *
316
- * Parse an attribute value into one or more Text and EntityReference nodes.
317
- *
318
- * Return 1 in case of success, 0 if the reader was not positionned on an
319
- * attribute node or all the attribute values have been read, or -1 in case of
320
- * error.
321
- */
322
- static VALUE
323
- ruby_xml_reader_read_attr_value(VALUE self)
324
- {
325
- return INT2FIX(xmlTextReaderReadAttributeValue(ruby_xml_text_reader_get(self)));
326
- }
327
-
328
- /*
329
- * call-seq:
330
- * reader.read_inner_xml -> data
331
- *
332
- * Read the contents of the current node, including child nodes and markup.
333
- *
334
- * Return a string containing the XML content, or nil if the current node is
335
- * neither an element nor attribute, or has no child nodes.
336
- */
337
- static VALUE
338
- ruby_xml_reader_read_inner_xml(VALUE self)
339
- {
340
- return CSTR2RVAL2(xmlTextReaderReadInnerXml(ruby_xml_text_reader_get(self)));
341
- }
342
-
343
- /*
344
- * call-seq:
345
- * reader.read_outer_xml -> data
346
- *
347
- * Read the contents of the current node, including child nodes and markup.
348
- *
349
- * Return a string containing the XML content, or nil if the current node is
350
- * neither an element nor attribute, or has no child nodes.
351
- */
352
- static VALUE
353
- ruby_xml_reader_read_outer_xml(VALUE self)
354
- {
355
- return CSTR2RVAL2(xmlTextReaderReadOuterXml(ruby_xml_text_reader_get(self)));
356
- }
357
-
358
- /*
359
- * call-seq:
360
- * reader.read_state -> state
361
- *
362
- * Get the read state of the reader.
363
- */
364
- static VALUE
365
- ruby_xml_reader_read_state(VALUE self)
366
- {
367
- return INT2FIX(xmlTextReaderReadState(ruby_xml_text_reader_get(self)));
368
- }
369
-
370
- /*
371
- * call-seq:
372
- * reader.read_string -> string
373
- *
374
- * Read the contents of an element or a text node as a string.
375
- *
376
- * Return a string containing the contents of the Element or Text node, or nil
377
- * if the reader is positioned on any other type of node.
378
- */
379
- static VALUE
380
- ruby_xml_reader_read_string(VALUE self)
381
- {
382
- return CSTR2RVAL2(xmlTextReaderReadString(ruby_xml_text_reader_get(self)));
383
- }
384
-
385
- static void
386
- __xml_reader_error_cb(void *arg,
387
- const char *msg, xmlParserSeverities severity,
388
- xmlTextReaderLocatorPtr locator)
389
- {
390
- VALUE reader;
391
- VALUE block;
392
-
393
- reader = (VALUE)arg;
394
- block = rb_ivar_get(reader, error_handler_block_ivar_id);
395
- if (NIL_P(block))
396
- rb_bug("no ivar block");
397
-
398
- rb_funcall(block,
399
- rb_intern("call"),
400
- 5,
401
- reader,
402
- CSTR2RVAL(msg),
403
- INT2FIX(severity),
404
- CSTR2RVAL2(xmlTextReaderLocatorBaseURI(locator)),
405
- INT2FIX(xmlTextReaderLocatorLineNumber(locator)));
406
- }
407
-
408
- /*
409
- * call-seq:
410
- * reader.set_error_handler { ... }
411
- *
412
- * Register a callback block that will be called on error and warnings. The
413
- * block will be called with 5 parameters: the reader, the error message, the
414
- * severity, the base URI and the line number.
415
- */
416
- static VALUE
417
- ruby_xml_reader_set_error_handler(VALUE self)
418
- {
419
- VALUE block;
420
- xmlTextReaderPtr reader;
421
-
422
- if (rb_block_given_p() == Qfalse)
423
- rb_raise(rb_eRuntimeError, "No block given");
424
-
425
- block = rb_block_proc();
426
-
427
- /* Embed the block within the parser object to avoid it to be collected.
428
- * Previous handler if exits is overwritten.
429
- */
430
- rb_ivar_set(self, error_handler_block_ivar_id, block);
431
- reader = ruby_xml_text_reader_get(self);
432
- xmlTextReaderSetErrorHandler(reader, __xml_reader_error_cb, (void *)self);
433
-
434
- return self;
435
- }
436
-
437
- /*
438
- * call-seq:
439
- * reader.reset_error_handler
440
- *
441
- * Restore the default error and warning handlers.
442
- */
443
- static VALUE
444
- ruby_xml_reader_reset_error_handler(VALUE self)
445
- {
446
- xmlTextReaderSetErrorHandler(ruby_xml_text_reader_get(self), NULL, NULL);
447
- return self;
448
- }
449
-
450
- /*
451
- * call-seq:
452
- * reader.relax_ng_validate(rng) -> code
453
- *
454
- * Use RelaxNG to validate the document as it is processed. Activation is only
455
- * possible before the first read. If +rng+ is nil, the RelaxNG validation is
456
- * desactivated.
457
- *
458
- * Return 0 in case the RelaxNG validation could be (des)activated and -1 in
459
- * case of error.
460
- */
461
- static VALUE
462
- ruby_xml_reader_relax_ng_validate(VALUE self, VALUE rng)
463
- {
464
- return INT2FIX(xmlTextReaderRelaxNGValidate(ruby_xml_text_reader_get(self), NIL_P(rng) ? NULL : RVAL2CSTR(rng)));
465
- }
466
-
467
- #if LIBXML_VERSION >= 20620
468
- /*
469
- * call-seq:
470
- * reader.schema_validate(schema) -> code
471
- *
472
- * Use W3C XSD schema to validate the document as it is processed. Activation
473
- * is only possible before the first read. If +schema+ is nil, then XML Schema
474
- * validation is desactivated.
475
- *
476
- * Return 0 in case the schemas validation could be (de)activated and -1 in
477
- * case of error.
478
- */
479
- static VALUE
480
- ruby_xml_reader_schema_validate(VALUE self, VALUE xsd)
481
- {
482
- return INT2FIX(xmlTextReaderSchemaValidate(ruby_xml_text_reader_get(self), NIL_P(xsd) ? NULL : RVAL2CSTR(xsd)));
483
- }
484
- #endif
485
-
486
- /*
487
- * call-seq:
488
- * reader.name -> name
489
- *
490
- * Return the qualified name of the node.
491
- */
492
- static VALUE
493
- ruby_xml_reader_name(VALUE self)
494
- {
495
- return CSTR2RVAL(xmlTextReaderConstName(ruby_xml_text_reader_get(self)));
496
- }
497
-
498
- /*
499
- * call-seq:
500
- * reader.local_name -> name
501
- *
502
- * Return the local name of the node.
503
- */
504
- static VALUE
505
- ruby_xml_reader_local_name(VALUE self)
506
- {
507
- return CSTR2RVAL(xmlTextReaderConstLocalName(ruby_xml_text_reader_get(self)));
508
- }
509
-
510
- /*
511
- * call-seq:
512
- * reader.attribute_count -> count
513
- *
514
- * Provide the number of attributes of the current node.
515
- */
516
- static VALUE
517
- ruby_xml_reader_attr_count(VALUE self)
518
- {
519
- return INT2FIX(xmlTextReaderAttributeCount(ruby_xml_text_reader_get(self)));
520
- }
521
-
522
- /*
523
- * call-seq:
524
- * reader.encoding -> encoding
525
- *
526
- * Determine the encoding of the document being read.
527
- */
528
- static VALUE
529
- ruby_xml_reader_encoding(VALUE self)
530
- {
531
- return CSTR2RVAL(xmlTextReaderConstEncoding(ruby_xml_text_reader_get(self)));
532
- }
533
-
534
- /*
535
- * call-seq:
536
- * reader.base_uri -> URI
537
- *
538
- * Determine the base URI of the node.
539
- */
540
- static VALUE
541
- ruby_xml_reader_base_uri(VALUE self)
542
- {
543
- return CSTR2RVAL(xmlTextReaderConstBaseUri(ruby_xml_text_reader_get(self)));
544
- }
545
-
546
- /*
547
- * call-seq:
548
- * reader.namespace_uri -> URI
549
- *
550
- * Determine the namespace URI of the node.
551
- */
552
- static VALUE
553
- ruby_xml_reader_namespace_uri(VALUE self)
554
- {
555
- return CSTR2RVAL(xmlTextReaderConstNamespaceUri(ruby_xml_text_reader_get(self)));
556
- }
557
-
558
- /*
559
- * call-seq:
560
- * reader.value -> text
561
- *
562
- * Provide the text value of the node if present.
563
- */
564
- static VALUE
565
- ruby_xml_reader_value(VALUE self)
566
- {
567
- return CSTR2RVAL(xmlTextReaderConstValue(ruby_xml_text_reader_get(self)));
568
- }
569
-
570
- /*
571
- * call-seq:
572
- * reader.prefix -> prefix
573
- *
574
- * Get a shorthand reference to the namespace associated with the node.
575
- */
576
- static VALUE
577
- ruby_xml_reader_prefix(VALUE self)
578
- {
579
- return CSTR2RVAL(xmlTextReaderConstPrefix(ruby_xml_text_reader_get(self)));
580
- }
581
-
582
- /*
583
- * call-seq:
584
- * reader.depth -> depth
585
- *
586
- * Get the depth of the node in the tree.
587
- */
588
- static VALUE
589
- ruby_xml_reader_depth(VALUE self)
590
- {
591
- return INT2FIX(xmlTextReaderDepth(ruby_xml_text_reader_get(self)));
592
- }
593
-
594
- /*
595
- * call-seq:
596
- * reader.quote_char -> char
597
- *
598
- * Get the quotation mark character used to enclose the value of an attribute,
599
- * as an integer value (and -1 in case of error).
600
- */
601
- static VALUE
602
- ruby_xml_reader_quote_char(VALUE self)
603
- {
604
- return INT2FIX(xmlTextReaderQuoteChar(ruby_xml_text_reader_get(self)));
605
- }
606
-
607
- /*
608
- * call-seq:
609
- * reader.standalone -> code
610
- *
611
- * Determine the standalone status of the document being read.
612
- *
613
- * Return 1 if the document was declared to be standalone, 0 if it was
614
- * declared to be not standalone, or -1 if the document did not specify its
615
- * standalone status or in case of error.
616
- */
617
- static VALUE
618
- ruby_xml_reader_standalone(VALUE self)
619
- {
620
- return INT2FIX(xmlTextReaderStandalone(ruby_xml_text_reader_get(self)));
621
- }
622
-
623
- /*
624
- * call-seq:
625
- * reader.xml_lang -> value
626
- *
627
- * Get the xml:lang scope within which the node resides.
628
- */
629
- static VALUE
630
- ruby_xml_reader_xml_lang(VALUE self)
631
- {
632
- return CSTR2RVAL(xmlTextReaderConstXmlLang(ruby_xml_text_reader_get(self)));
633
- }
634
-
635
- /*
636
- * call-seq:
637
- * reader.xml_version -> version
638
- *
639
- * Determine the XML version of the document being read.
640
- */
641
- static VALUE
642
- ruby_xml_reader_xml_version(VALUE self)
643
- {
644
- return CSTR2RVAL(xmlTextReaderConstXmlVersion(ruby_xml_text_reader_get(self)));
645
- }
646
-
647
- /*
648
- * call-seq:
649
- * reader.has_attributes? -> bool
650
- *
651
- * Get whether the node has attributes.
652
- */
653
- static VALUE
654
- ruby_xml_reader_has_attributes(VALUE self)
655
- {
656
- return xmlTextReaderHasAttributes(ruby_xml_text_reader_get(self)) ? Qtrue : Qfalse;
657
- }
658
-
659
- /*
660
- * call-seq:
661
- * reader.has_value? -> bool
662
- *
663
- * Get whether the node can have a text value.
664
- */
665
- static VALUE
666
- ruby_xml_reader_has_value(VALUE self)
667
- {
668
- return xmlTextReaderHasValue(ruby_xml_text_reader_get(self)) ? Qtrue : Qfalse;
669
- }
670
-
671
- /*
672
- * call-seq:
673
- * reader[key] -> value
674
- *
675
- * Provide the value of the attribute with the specified index (if +key+ is an
676
- * integer) or with the specified name (if +key+ is a string) relative to the
677
- * containing element, as a string.
678
- */
679
- static VALUE
680
- ruby_xml_reader_attribute(VALUE self, VALUE key)
681
- {
682
- xmlTextReaderPtr reader;
683
- xmlChar *attr;
684
-
685
- reader = ruby_xml_text_reader_get(self);
686
-
687
- if (TYPE(key) == T_FIXNUM) {
688
- attr = xmlTextReaderGetAttributeNo(reader, FIX2INT(key));
689
- }
690
- else {
691
- attr = xmlTextReaderGetAttribute(reader, (const xmlChar *)RVAL2CSTR(key));
692
- }
693
- return CSTR2RVAL2(attr);
694
- }
695
-
696
- /*
697
- * call-seq:
698
- * reader.lookup_namespace(prefix) -> value
699
- *
700
- * Resolve a namespace prefix in the scope of the current element.
701
- * To return the default namespace, specify nil as +prefix+.
702
- */
703
- static VALUE
704
- ruby_xml_reader_lookup_namespace(VALUE self, VALUE prefix)
705
- {
706
- return CSTR2RVAL2(xmlTextReaderLookupNamespace(ruby_xml_text_reader_get(self), (const xmlChar *)RVAL2CSTR(prefix)));
707
- }
708
-
709
- /*
710
- * call-seq:
711
- * reader.expand -> node
712
- *
713
- * Read the contents of the current node and the full subtree. It then makes
714
- * the subtree available until the next read call.
715
- *
716
- * Return an XML::Node object, or nil in case of error.
717
- */
718
- static VALUE
719
- ruby_xml_reader_expand(VALUE self)
720
- {
721
- xmlNodePtr node;
722
- xmlDocPtr doc;
723
- xmlTextReaderPtr reader = ruby_xml_text_reader_get(self);
724
- node = xmlTextReaderExpand(reader);
725
-
726
- if (!node)
727
- return Qnil;
728
-
729
- /* Okay this is tricky. By accessing the returned node, we
730
- take ownership of the reader's document. Thus we need to
731
- tell the reader to not free it. Otherwise it will be
732
- freed twice - once when the Ruby document wrapper goes
733
- out of scope and once when the reader goes out of scope. */
734
-
735
- xmlTextReaderPreserve(reader);
736
- doc = xmlTextReaderCurrentDoc(reader);
737
- ruby_xml_document_wrap(doc);
738
-
739
- return ruby_xml_node2_wrap(cXMLNode, node);
740
- }
741
-
742
- #if LIBXML_VERSION >= 20618
743
- /*
744
- * call-seq:
745
- * reader.byte_consumed -> value
746
- *
747
- * This method provides the current index of the parser used by the reader,
748
- * relative to the start of the current entity.
749
- */
750
- static VALUE
751
- ruby_xml_reader_byte_consumed(VALUE self)
752
- {
753
- return INT2NUM(xmlTextReaderByteConsumed(ruby_xml_text_reader_get(self)));
754
- }
755
- #endif
756
-
757
- #if LIBXML_VERSION >= 20617
758
- /*
759
- * call-seq:
760
- * reader.column_number -> number
761
- *
762
- * Provide the column number of the current parsing point.
763
- */
764
- static VALUE
765
- ruby_xml_reader_column_number(VALUE self)
766
- {
767
- return INT2NUM(xmlTextReaderGetParserColumnNumber(ruby_xml_text_reader_get(self)));
768
- }
769
-
770
- /*
771
- * call-seq:
772
- * reader.line_number -> number
773
- *
774
- * Provide the line number of the current parsing point.
775
- */
776
- static VALUE
777
- ruby_xml_reader_line_number(VALUE self)
778
- {
779
- return INT2NUM(xmlTextReaderGetParserLineNumber(ruby_xml_text_reader_get(self)));
780
- }
781
- #endif
782
-
783
- /*
784
- * call-seq:
785
- * reader.default? -> bool
786
- *
787
- * Return whether an Attribute node was generated from the default value
788
- * defined in the DTD or schema.
789
- */
790
- static VALUE
791
- ruby_xml_reader_default(VALUE self)
792
- {
793
- return xmlTextReaderIsDefault(ruby_xml_text_reader_get(self)) ? Qtrue : Qfalse;
794
- }
795
-
796
- /*
797
- * call-seq:
798
- * reader.namespace_declaration? -> bool
799
- *
800
- * Determine whether the current node is a namespace declaration rather than a
801
- * regular attribute.
802
- */
803
- static VALUE
804
- ruby_xml_reader_namespace_declaration(VALUE self)
805
- {
806
- return xmlTextReaderIsNamespaceDecl(ruby_xml_text_reader_get(self)) ? Qtrue : Qfalse;
807
- }
808
-
809
- /*
810
- * call-seq:
811
- * reader.empty_element? -> bool
812
- *
813
- * Check if the current node is empty.
814
- */
815
- static VALUE
816
- ruby_xml_reader_empty_element(VALUE self)
817
- {
818
- return xmlTextReaderIsEmptyElement(ruby_xml_text_reader_get(self)) ? Qtrue : Qfalse;
819
- }
820
-
821
- /*
822
- * call-seq:
823
- * reader.valid? -> bool
824
- *
825
- * Retrieve the validity status from the parser context.
826
- */
827
- static VALUE
828
- ruby_xml_reader_valid(VALUE self)
829
- {
830
- return xmlTextReaderIsValid(ruby_xml_text_reader_get(self)) ? Qtrue : Qfalse;
831
- }
832
-
833
- /* Rdoc needs to know. */
834
- #ifdef RDOC_NEVER_DEFINED
835
- mLibXML = rb_define_module("LibXML");
836
- mXML = rb_define_module_under(mLibXML, "XML");
837
- #endif
838
-
839
- void
840
- ruby_init_xml_reader(void)
841
- {
842
- cXMLReader = rb_define_class_under(mXML, "Reader", rb_cObject);
843
- error_handler_block_ivar_id = rb_intern("@__error_handler_callback__");
844
-
845
- rb_define_singleton_method(cXMLReader, "file", ruby_xml_reader_new_file, -1);
846
- rb_define_singleton_method(cXMLReader, "io", ruby_xml_reader_new_io, -1);
847
- rb_define_singleton_method(cXMLReader, "walker", ruby_xml_reader_new_walker, 1);
848
- rb_define_alias(CLASS_OF(cXMLReader), "document", "walker");
849
- rb_define_singleton_method(cXMLReader, "new", ruby_xml_reader_new_data, -1);
850
- rb_define_alias(CLASS_OF(cXMLReader), "string", "new");
851
-
852
- rb_define_method(cXMLReader, "close", ruby_xml_reader_close, 0);
853
-
854
- rb_define_method(cXMLReader, "move_to_attribute", ruby_xml_reader_move_to_attr, 1);
855
- rb_define_method(cXMLReader, "move_to_first_attribute", ruby_xml_reader_move_to_first_attr, 0);
856
- rb_define_method(cXMLReader, "move_to_next_attribute", ruby_xml_reader_move_to_next_attr, 0);
857
- rb_define_method(cXMLReader, "move_to_element", ruby_xml_reader_move_to_element, 0);
858
- rb_define_method(cXMLReader, "next", ruby_xml_reader_next, 0);
859
- rb_define_method(cXMLReader, "next_sibling", ruby_xml_reader_next_sibling, 0);
860
- rb_define_method(cXMLReader, "read", ruby_xml_reader_read, 0);
861
- rb_define_method(cXMLReader, "read_attribute_value", ruby_xml_reader_read_attr_value, 0);
862
- rb_define_method(cXMLReader, "read_inner_xml", ruby_xml_reader_read_inner_xml, 0);
863
- rb_define_method(cXMLReader, "read_outer_xml", ruby_xml_reader_read_outer_xml, 0);
864
- rb_define_method(cXMLReader, "read_state", ruby_xml_reader_read_state, 0);
865
- rb_define_method(cXMLReader, "read_string", ruby_xml_reader_read_string, 0);
866
-
867
- rb_define_method(cXMLReader, "set_error_handler", ruby_xml_reader_set_error_handler, 0);
868
- rb_define_method(cXMLReader, "reset_error_handler", ruby_xml_reader_reset_error_handler, 0);
869
-
870
- rb_define_method(cXMLReader, "relax_ng_validate", ruby_xml_reader_relax_ng_validate, 1);
871
- #if LIBXML_VERSION >= 20620
872
- rb_define_method(cXMLReader, "schema_validate", ruby_xml_reader_schema_validate, 1);
873
- #endif
874
-
875
- rb_define_method(cXMLReader, "node_type", ruby_xml_reader_node_type, 0);
876
- rb_define_method(cXMLReader, "normalization", ruby_xml_reader_normalization, 0);
877
- rb_define_method(cXMLReader, "attribute_count", ruby_xml_reader_attr_count, 0);
878
- rb_define_method(cXMLReader, "name", ruby_xml_reader_name, 0);
879
- rb_define_method(cXMLReader, "local_name", ruby_xml_reader_local_name, 0);
880
- rb_define_method(cXMLReader, "encoding", ruby_xml_reader_encoding, 0);
881
- rb_define_method(cXMLReader, "base_uri", ruby_xml_reader_base_uri, 0);
882
- rb_define_method(cXMLReader, "namespace_uri", ruby_xml_reader_namespace_uri, 0);
883
- rb_define_method(cXMLReader, "xml_lang", ruby_xml_reader_xml_lang, 0);
884
- rb_define_method(cXMLReader, "xml_version", ruby_xml_reader_xml_version, 0);
885
- rb_define_method(cXMLReader, "prefix", ruby_xml_reader_prefix, 0);
886
- rb_define_method(cXMLReader, "depth", ruby_xml_reader_depth, 0);
887
- rb_define_method(cXMLReader, "quote_char", ruby_xml_reader_quote_char, 0);
888
- rb_define_method(cXMLReader, "standalone", ruby_xml_reader_standalone, 0);
889
-
890
- rb_define_method(cXMLReader, "has_attributes?", ruby_xml_reader_has_attributes, 0);
891
- rb_define_method(cXMLReader, "[]", ruby_xml_reader_attribute, 1);
892
- rb_define_method(cXMLReader, "has_value?", ruby_xml_reader_has_value, 0);
893
- rb_define_method(cXMLReader, "value", ruby_xml_reader_value, 0);
894
-
895
- rb_define_method(cXMLReader, "lookup_namespace", ruby_xml_reader_lookup_namespace, 1);
896
- rb_define_method(cXMLReader, "expand", ruby_xml_reader_expand, 0);
897
-
898
- #if LIBXML_VERSION >= 20618
899
- rb_define_method(cXMLReader, "byte_consumed", ruby_xml_reader_byte_consumed, 0);
900
- #endif
901
- #if LIBXML_VERSION >= 20617
902
- rb_define_method(cXMLReader, "column_number", ruby_xml_reader_column_number, 0);
903
- rb_define_method(cXMLReader, "line_number", ruby_xml_reader_line_number, 0);
904
- #endif
905
- rb_define_method(cXMLReader, "default?", ruby_xml_reader_default, 0);
906
- rb_define_method(cXMLReader, "empty_element?", ruby_xml_reader_empty_element, 0);
907
- rb_define_method(cXMLReader, "namespace_declaration?", ruby_xml_reader_namespace_declaration, 0);
908
- rb_define_method(cXMLReader, "valid?", ruby_xml_reader_valid, 0);
909
-
910
- rb_define_const(cXMLReader, "LOADDTD", INT2FIX(XML_PARSER_LOADDTD));
911
- rb_define_const(cXMLReader, "DEFAULTATTRS", INT2FIX(XML_PARSER_DEFAULTATTRS));
912
- rb_define_const(cXMLReader, "VALIDATE", INT2FIX(XML_PARSER_VALIDATE));
913
- rb_define_const(cXMLReader, "SUBST_ENTITIES", INT2FIX(XML_PARSER_SUBST_ENTITIES));
914
-
915
- rb_define_const(cXMLReader, "SEVERITY_VALIDITY_WARNING", INT2FIX(XML_PARSER_SEVERITY_VALIDITY_WARNING));
916
- rb_define_const(cXMLReader, "SEVERITY_VALIDITY_ERROR", INT2FIX(XML_PARSER_SEVERITY_VALIDITY_ERROR));
917
- rb_define_const(cXMLReader, "SEVERITY_WARNING", INT2FIX(XML_PARSER_SEVERITY_WARNING));
918
- rb_define_const(cXMLReader, "SEVERITY_ERROR", INT2FIX(XML_PARSER_SEVERITY_ERROR));
919
-
920
- rb_define_const(cXMLReader, "TYPE_NONE", INT2FIX(XML_READER_TYPE_NONE));
921
- rb_define_const(cXMLReader, "TYPE_ELEMENT", INT2FIX(XML_READER_TYPE_ELEMENT));
922
- rb_define_const(cXMLReader, "TYPE_ATTRIBUTE", INT2FIX(XML_READER_TYPE_ATTRIBUTE));
923
- rb_define_const(cXMLReader, "TYPE_TEXT", INT2FIX(XML_READER_TYPE_TEXT));
924
- rb_define_const(cXMLReader, "TYPE_CDATA", INT2FIX(XML_READER_TYPE_CDATA));
925
- rb_define_const(cXMLReader, "TYPE_ENTITY_REFERENCE", INT2FIX(XML_READER_TYPE_ENTITY_REFERENCE));
926
- rb_define_const(cXMLReader, "TYPE_ENTITY", INT2FIX(XML_READER_TYPE_ENTITY));
927
- rb_define_const(cXMLReader, "TYPE_PROCESSING_INSTRUCTION", INT2FIX(XML_READER_TYPE_PROCESSING_INSTRUCTION));
928
- rb_define_const(cXMLReader, "TYPE_COMMENT", INT2FIX(XML_READER_TYPE_COMMENT));
929
- rb_define_const(cXMLReader, "TYPE_DOCUMENT", INT2FIX(XML_READER_TYPE_DOCUMENT));
930
- rb_define_const(cXMLReader, "TYPE_DOCUMENT_TYPE", INT2FIX(XML_READER_TYPE_DOCUMENT_TYPE));
931
- rb_define_const(cXMLReader, "TYPE_DOCUMENT_FRAGMENT", INT2FIX(XML_READER_TYPE_DOCUMENT_FRAGMENT));
932
- rb_define_const(cXMLReader, "TYPE_NOTATION", INT2FIX(XML_READER_TYPE_NOTATION));
933
- rb_define_const(cXMLReader, "TYPE_WHITESPACE", INT2FIX(XML_READER_TYPE_WHITESPACE));
934
- rb_define_const(cXMLReader, "TYPE_SIGNIFICANT_WHITESPACE", INT2FIX(XML_READER_TYPE_SIGNIFICANT_WHITESPACE));
935
- rb_define_const(cXMLReader, "TYPE_END_ELEMENT", INT2FIX(XML_READER_TYPE_END_ELEMENT));
936
- rb_define_const(cXMLReader, "TYPE_END_ENTITY", INT2FIX(XML_READER_TYPE_END_ENTITY));
937
- rb_define_const(cXMLReader, "TYPE_XML_DECLARATION", INT2FIX(XML_READER_TYPE_XML_DECLARATION));
938
-
939
- rb_define_const(cXMLReader, "MODE_INITIAL", INT2FIX(XML_TEXTREADER_MODE_INITIAL));
940
- rb_define_const(cXMLReader, "MODE_INTERACTIVE", INT2FIX(XML_TEXTREADER_MODE_INTERACTIVE));
941
- rb_define_const(cXMLReader, "MODE_ERROR", INT2FIX(XML_TEXTREADER_MODE_ERROR));
942
- rb_define_const(cXMLReader, "MODE_EOF", INT2FIX(XML_TEXTREADER_MODE_EOF));
943
- rb_define_const(cXMLReader, "MODE_CLOSED", INT2FIX(XML_TEXTREADER_MODE_CLOSED));
944
- rb_define_const(cXMLReader, "MODE_READING", INT2FIX(XML_TEXTREADER_MODE_READING));
945
- }
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
+ VALUE cXMLReader;
8
+
9
+ /*
10
+ * Document-class: LibXML::XML::Reader
11
+ *
12
+ * The XML::Reader class provides a simpler, alternative way of parsing an XML
13
+ * document in contrast to XML::Parser or XML::SaxParser. A XML::Reader instance
14
+ * acts like a cursor going forward in a document stream, stopping at each node
15
+ * it encounters. To advance to the next node, simply cadd XML::Reader#read.
16
+ *
17
+ * The XML::Reader API closely matches the DOM Core specification and supports
18
+ * namespaces, xml:base, entity handling and DTDs.
19
+ *
20
+ * To summarize, XML::Reader provides a far simpler API to use versus XML::SaxParser
21
+ * and is more memory efficient than using XML::Parser to create a DOM tree.
22
+ *
23
+ * Example:
24
+ *
25
+ * parser = XML::Reader.new("<foo><bar>1</bar><bar>2</bar><bar>3</bar></foo>")
26
+ * parser.read
27
+ * assert_equal('foo', parser.name)
28
+ * assert_equal(nil, parser.value)
29
+ *
30
+ * 3.times do |i|
31
+ * parser.read
32
+ * assert_equal(XML::Reader::TYPE_ELEMENT, parser.node_type)
33
+ * assert_equal('bar', parser.name)
34
+ * parser.read
35
+ * assert_equal(XML::Reader::TYPE_TEXT, parser.node_type)
36
+ * assert_equal((i + 1).to_s, parser.value)
37
+ * parser.read
38
+ * assert_equal(XML::Reader::TYPE_END_ELEMENT, parser.node_type)
39
+ * end
40
+ *
41
+ * For a more in depth tutorial, albeit in C, see http://xmlsoft.org/xmlreader.html.*/
42
+
43
+ #define CSTR2RVAL(x) (x == NULL ? Qnil : rb_str_new2((const char *)x))
44
+ #define RVAL2CSTR(x) (StringValueCStr(x))
45
+
46
+ static inline VALUE
47
+ __rb_str_new_and_free(xmlChar *x)
48
+ {
49
+ if (x != NULL) {
50
+ VALUE v = rb_str_new2((const char *)x);
51
+ xmlFree(x);
52
+ return v;
53
+ }
54
+ return Qnil;
55
+ }
56
+
57
+ #define CSTR2RVAL2(x) (__rb_str_new_and_free(x))
58
+
59
+ static int
60
+ ctxtRead(FILE *f, char * buf, size_t len) {
61
+ return(fread(buf, 1, len, f));
62
+ }
63
+
64
+ static VALUE
65
+ ruby_xml_reader_new(VALUE class, xmlTextReaderPtr reader)
66
+ {
67
+ return Data_Wrap_Struct(class, NULL, xmlFreeTextReader, reader);
68
+ }
69
+
70
+ static xmlTextReaderPtr
71
+ ruby_xml_text_reader_get(VALUE obj)
72
+ {
73
+ xmlTextReaderPtr ptr;
74
+ Data_Get_Struct(obj, xmlTextReader, ptr);
75
+ return ptr;
76
+ }
77
+
78
+ /*
79
+ * call-seq:
80
+ * XML::Reader.file(path, encoding=nil, options=0) -> reader
81
+ *
82
+ * Parse an XML file from the filesystem or the network. The parsing flags
83
+ * options are a combination of xmlParserOption.
84
+ */
85
+ static VALUE
86
+ ruby_xml_reader_new_file(int argc, VALUE *argv, VALUE self)
87
+ {
88
+ xmlTextReaderPtr reader;
89
+ VALUE path, encoding, options;
90
+
91
+ rb_scan_args(argc, argv, "12", &path, &encoding, &options);
92
+
93
+ reader = xmlReaderForFile(RVAL2CSTR(path),
94
+ NIL_P(encoding) ? NULL : RVAL2CSTR(encoding),
95
+ NIL_P(options) ? 0 : FIX2INT(options));
96
+ if (reader == NULL)
97
+ rb_raise(rb_eRuntimeError,
98
+ "cannot create text reader for given XML file at path '%s'",
99
+ RVAL2CSTR(path));
100
+
101
+ return ruby_xml_reader_new(self, reader);
102
+ }
103
+
104
+ /*
105
+ * call-seq:
106
+ * XML::Reader.io(io, url=nil, encoding=nil, options=0) -> reader
107
+ *
108
+ * Parse an XML file from a file handle. The parsing flags options are
109
+ * a combination of xmlParserOption.
110
+ */
111
+ static VALUE
112
+ ruby_xml_reader_new_io(int argc, VALUE *argv, VALUE self)
113
+ {
114
+ xmlTextReaderPtr reader;
115
+ VALUE io, url, encoding, options;
116
+ OpenFile *fptr;
117
+ FILE *f;
118
+
119
+ #ifdef _WIN32
120
+ rb_raise(rb_eRuntimeError, "Reading an io stream is not supported on Windows");
121
+ #endif
122
+
123
+ rb_scan_args(argc, argv, "13", &io, &url, &encoding, &options);
124
+
125
+ if (!rb_obj_is_kind_of(io, rb_cIO))
126
+ rb_raise(rb_eTypeError, "need an IO object");
127
+
128
+ GetOpenFile(io, fptr);
129
+ rb_io_check_readable(fptr);
130
+ f = GetWriteFile(fptr);
131
+
132
+ reader = xmlReaderForIO((xmlInputReadCallback) ctxtRead, NULL, f,
133
+ NIL_P(url) ? NULL : RVAL2CSTR(url),
134
+ NIL_P(encoding) ? NULL : RVAL2CSTR(encoding),
135
+ NIL_P(options) ? 0 : FIX2INT(options));
136
+ if (reader == NULL)
137
+ rb_raise(rb_eRuntimeError, "cannot create text reader for given stream");
138
+
139
+ return ruby_xml_reader_new(self, reader);
140
+ }
141
+
142
+ /*
143
+ * call-seq:
144
+ * XML::Reader.walker(doc) -> reader
145
+ * XML::Reader.document(doc) -> reader
146
+ *
147
+ * Create an XML text reader for a preparsed document.
148
+ */
149
+ VALUE
150
+ ruby_xml_reader_new_walker(VALUE self, VALUE doc)
151
+ {
152
+ xmlDocPtr xdoc;
153
+ xmlTextReaderPtr reader;
154
+
155
+ Data_Get_Struct(doc, xmlDoc, xdoc);
156
+
157
+ reader = xmlReaderWalker(xdoc);
158
+ if (reader == NULL)
159
+ rb_raise(rb_eRuntimeError, "cannot create text reader for given document");
160
+
161
+ return ruby_xml_reader_new(self, reader);
162
+ }
163
+
164
+ /*
165
+ * call-seq:
166
+ * XML::Reader.new(data, url=nil, encoding=nil, options=0) -> reader
167
+ * XML::Reader.string(data, url=nil, encoding=nil, options=0) -> reader
168
+ *
169
+ * Create an XML text reader for an XML in-memory document. The parsing flags
170
+ * options are a combination of xmlParserOption.
171
+ */
172
+ static VALUE
173
+ ruby_xml_reader_new_data(int argc, VALUE *argv, VALUE self)
174
+ {
175
+ xmlTextReaderPtr reader;
176
+ VALUE data, url, encoding, options;
177
+ char *c_data;
178
+
179
+ rb_scan_args(argc, argv, "13", &data, &url, &encoding, &options);
180
+
181
+ c_data = RVAL2CSTR(data);
182
+ reader = xmlReaderForMemory(c_data,
183
+ strlen(c_data),
184
+ NIL_P(url) ? NULL : RVAL2CSTR(url),
185
+ NIL_P(encoding) ? NULL : RVAL2CSTR(encoding),
186
+ NIL_P(options) ? 0 : FIX2INT(options));
187
+ if (reader == NULL)
188
+ rb_raise(rb_eRuntimeError, "cannot create text reader for given data");
189
+
190
+ return ruby_xml_reader_new(self, reader);
191
+ }
192
+
193
+ /*
194
+ * call-seq:
195
+ * parser.close -> code
196
+ *
197
+ * This method releases any resources allocated by the current instance
198
+ * changes the state to Closed and close any underlying input.
199
+ */
200
+ static VALUE
201
+ ruby_xml_reader_close(VALUE self)
202
+ {
203
+ return INT2FIX(xmlTextReaderClose(ruby_xml_text_reader_get(self)));
204
+ }
205
+
206
+ /*
207
+ * call-seq:
208
+ * parser.move_to_attribute(val) -> code
209
+ *
210
+ * Move the position of the current instance to the attribute with the
211
+ * specified index (if +val+ is an integer) or name (if +val+ is a string)
212
+ * relative to the containing element.
213
+ */
214
+ static VALUE
215
+ ruby_xml_reader_move_to_attr(VALUE self, VALUE val)
216
+ {
217
+ xmlTextReaderPtr reader;
218
+ int ret;
219
+
220
+ reader = ruby_xml_text_reader_get(self);
221
+
222
+ if (TYPE(val) == T_FIXNUM) {
223
+ ret = xmlTextReaderMoveToAttributeNo(reader, FIX2INT(val));
224
+ }
225
+ else {
226
+ ret = xmlTextReaderMoveToAttribute(reader, (const xmlChar *)RVAL2CSTR(val));
227
+ }
228
+
229
+ return INT2FIX(ret);
230
+ }
231
+
232
+ /*
233
+ * call-seq:
234
+ * reader.move_to_first_attribute -> code
235
+ *
236
+ * Move the position of the current instance to the first attribute associated
237
+ * with the current node.
238
+ */
239
+ static VALUE
240
+ ruby_xml_reader_move_to_first_attr(VALUE self)
241
+ {
242
+ return INT2FIX(xmlTextReaderMoveToFirstAttribute(ruby_xml_text_reader_get(self)));
243
+ }
244
+
245
+ /*
246
+ * call-seq:
247
+ * reader.move_to_next_attribute -> code
248
+ *
249
+ * Move the position of the current instance to the next attribute associated
250
+ * with the current node.
251
+ */
252
+ static VALUE
253
+ ruby_xml_reader_move_to_next_attr(VALUE self)
254
+ {
255
+ return INT2FIX(xmlTextReaderMoveToNextAttribute(ruby_xml_text_reader_get(self)));
256
+ }
257
+
258
+ /*
259
+ * call-seq:
260
+ * reader.move_to_element -> code
261
+ *
262
+ * Move the position of the current instance to the node that contains the
263
+ * current attribute node.
264
+ */
265
+ static VALUE
266
+ ruby_xml_reader_move_to_element(VALUE self)
267
+ {
268
+ return INT2FIX(xmlTextReaderMoveToElement(ruby_xml_text_reader_get(self)));
269
+ }
270
+
271
+ /*
272
+ * call-seq:
273
+ * reader.next -> code
274
+ *
275
+ * Skip to the node following the current one in document order while avoiding
276
+ * the subtree if any.
277
+ */
278
+ static VALUE
279
+ ruby_xml_reader_next(VALUE self)
280
+ {
281
+ return INT2FIX(xmlTextReaderNext(ruby_xml_text_reader_get(self)));
282
+ }
283
+
284
+ /*
285
+ * call-seq:
286
+ * reader.next_sibling -> code
287
+ *
288
+ * Skip to the node following the current one in document order while avoiding
289
+ * the subtree if any. Currently implemented only for Readers built on a
290
+ * document.
291
+ */
292
+ static VALUE
293
+ ruby_xml_reader_next_sibling(VALUE self)
294
+ {
295
+ return INT2FIX(xmlTextReaderNextSibling(ruby_xml_text_reader_get(self)));
296
+ }
297
+
298
+ /*
299
+ * call-seq:
300
+ * reader.node_type -> type
301
+ *
302
+ * Get the node type of the current node. Reference:
303
+ * http://dotgnu.org/pnetlib-doc/System/Xml/XmlNodeType.html
304
+ */
305
+ static VALUE
306
+ ruby_xml_reader_node_type(VALUE self)
307
+ {
308
+ return INT2FIX(xmlTextReaderNodeType(ruby_xml_text_reader_get(self)));
309
+ }
310
+
311
+ /*
312
+ * call-seq:
313
+ * reader.normalization -> value
314
+ *
315
+ * The value indicating whether to normalize white space and attribute values.
316
+ * Since attribute value and end of line normalizations are a MUST in the XML
317
+ * specification only the value true is accepted. The broken bahaviour of
318
+ * accepting out of range character entities like &#0; is of course not
319
+ * supported either.
320
+ *
321
+ * Return 1 or -1 in case of error.
322
+ */
323
+ static VALUE
324
+ ruby_xml_reader_normalization(VALUE self)
325
+ {
326
+ return INT2FIX(xmlTextReaderNormalization(ruby_xml_text_reader_get(self)));
327
+ }
328
+
329
+ /*
330
+ * call-seq:
331
+ * reader.read -> code
332
+ *
333
+ * Move the position of the current instance to the next node in the stream,
334
+ * exposing its properties.
335
+ *
336
+ * Return 1 if the node was read successfully, 0 if there is no more nodes to
337
+ * read, or -1 in case of error.
338
+ */
339
+ static VALUE
340
+ ruby_xml_reader_read(VALUE self)
341
+ {
342
+ return INT2FIX(xmlTextReaderRead(ruby_xml_text_reader_get(self)));
343
+ }
344
+
345
+ /*
346
+ * call-seq:
347
+ * reader.read_attribute_value -> code
348
+ *
349
+ * Parse an attribute value into one or more Text and EntityReference nodes.
350
+ *
351
+ * Return 1 in case of success, 0 if the reader was not positionned on an
352
+ * attribute node or all the attribute values have been read, or -1 in case of
353
+ * error.
354
+ */
355
+ static VALUE
356
+ ruby_xml_reader_read_attr_value(VALUE self)
357
+ {
358
+ return INT2FIX(xmlTextReaderReadAttributeValue(ruby_xml_text_reader_get(self)));
359
+ }
360
+
361
+ /*
362
+ * call-seq:
363
+ * reader.read_inner_xml -> data
364
+ *
365
+ * Read the contents of the current node, including child nodes and markup.
366
+ *
367
+ * Return a string containing the XML content, or nil if the current node is
368
+ * neither an element nor attribute, or has no child nodes.
369
+ */
370
+ static VALUE
371
+ ruby_xml_reader_read_inner_xml(VALUE self)
372
+ {
373
+ return CSTR2RVAL2(xmlTextReaderReadInnerXml(ruby_xml_text_reader_get(self)));
374
+ }
375
+
376
+ /*
377
+ * call-seq:
378
+ * reader.read_outer_xml -> data
379
+ *
380
+ * Read the contents of the current node, including child nodes and markup.
381
+ *
382
+ * Return a string containing the XML content, or nil if the current node is
383
+ * neither an element nor attribute, or has no child nodes.
384
+ */
385
+ static VALUE
386
+ ruby_xml_reader_read_outer_xml(VALUE self)
387
+ {
388
+ return CSTR2RVAL2(xmlTextReaderReadOuterXml(ruby_xml_text_reader_get(self)));
389
+ }
390
+
391
+ /*
392
+ * call-seq:
393
+ * reader.read_state -> state
394
+ *
395
+ * Get the read state of the reader.
396
+ */
397
+ static VALUE
398
+ ruby_xml_reader_read_state(VALUE self)
399
+ {
400
+ return INT2FIX(xmlTextReaderReadState(ruby_xml_text_reader_get(self)));
401
+ }
402
+
403
+ /*
404
+ * call-seq:
405
+ * reader.read_string -> string
406
+ *
407
+ * Read the contents of an element or a text node as a string.
408
+ *
409
+ * Return a string containing the contents of the Element or Text node, or nil
410
+ * if the reader is positioned on any other type of node.
411
+ */
412
+ static VALUE
413
+ ruby_xml_reader_read_string(VALUE self)
414
+ {
415
+ return CSTR2RVAL2(xmlTextReaderReadString(ruby_xml_text_reader_get(self)));
416
+ }
417
+
418
+ /*
419
+ * call-seq:
420
+ * reader.relax_ng_validate(rng) -> code
421
+ *
422
+ * Use RelaxNG to validate the document as it is processed. Activation is only
423
+ * possible before the first read. If +rng+ is nil, the RelaxNG validation is
424
+ * desactivated.
425
+ *
426
+ * Return 0 in case the RelaxNG validation could be (des)activated and -1 in
427
+ * case of error.
428
+ */
429
+ static VALUE
430
+ ruby_xml_reader_relax_ng_validate(VALUE self, VALUE rng)
431
+ {
432
+ return INT2FIX(xmlTextReaderRelaxNGValidate(ruby_xml_text_reader_get(self), NIL_P(rng) ? NULL : RVAL2CSTR(rng)));
433
+ }
434
+
435
+ #if LIBXML_VERSION >= 20620
436
+ /*
437
+ * call-seq:
438
+ * reader.schema_validate(schema) -> code
439
+ *
440
+ * Use W3C XSD schema to validate the document as it is processed. Activation
441
+ * is only possible before the first read. If +schema+ is nil, then XML Schema
442
+ * validation is desactivated.
443
+ *
444
+ * Return 0 in case the schemas validation could be (de)activated and -1 in
445
+ * case of error.
446
+ */
447
+ static VALUE
448
+ ruby_xml_reader_schema_validate(VALUE self, VALUE xsd)
449
+ {
450
+ return INT2FIX(xmlTextReaderSchemaValidate(ruby_xml_text_reader_get(self), NIL_P(xsd) ? NULL : RVAL2CSTR(xsd)));
451
+ }
452
+ #endif
453
+
454
+ /*
455
+ * call-seq:
456
+ * reader.name -> name
457
+ *
458
+ * Return the qualified name of the node.
459
+ */
460
+ static VALUE
461
+ ruby_xml_reader_name(VALUE self)
462
+ {
463
+ return CSTR2RVAL(xmlTextReaderConstName(ruby_xml_text_reader_get(self)));
464
+ }
465
+
466
+ /*
467
+ * call-seq:
468
+ * reader.local_name -> name
469
+ *
470
+ * Return the local name of the node.
471
+ */
472
+ static VALUE
473
+ ruby_xml_reader_local_name(VALUE self)
474
+ {
475
+ return CSTR2RVAL(xmlTextReaderConstLocalName(ruby_xml_text_reader_get(self)));
476
+ }
477
+
478
+ /*
479
+ * call-seq:
480
+ * reader.attribute_count -> count
481
+ *
482
+ * Provide the number of attributes of the current node.
483
+ */
484
+ static VALUE
485
+ ruby_xml_reader_attr_count(VALUE self)
486
+ {
487
+ return INT2FIX(xmlTextReaderAttributeCount(ruby_xml_text_reader_get(self)));
488
+ }
489
+
490
+ /*
491
+ * call-seq:
492
+ * reader.encoding -> encoding
493
+ *
494
+ * Determine the encoding of the document being read.
495
+ */
496
+ static VALUE
497
+ ruby_xml_reader_encoding(VALUE self)
498
+ {
499
+ return CSTR2RVAL(xmlTextReaderConstEncoding(ruby_xml_text_reader_get(self)));
500
+ }
501
+
502
+ /*
503
+ * call-seq:
504
+ * reader.base_uri -> URI
505
+ *
506
+ * Determine the base URI of the node.
507
+ */
508
+ static VALUE
509
+ ruby_xml_reader_base_uri(VALUE self)
510
+ {
511
+ return CSTR2RVAL(xmlTextReaderConstBaseUri(ruby_xml_text_reader_get(self)));
512
+ }
513
+
514
+ /*
515
+ * call-seq:
516
+ * reader.namespace_uri -> URI
517
+ *
518
+ * Determine the namespace URI of the node.
519
+ */
520
+ static VALUE
521
+ ruby_xml_reader_namespace_uri(VALUE self)
522
+ {
523
+ return CSTR2RVAL(xmlTextReaderConstNamespaceUri(ruby_xml_text_reader_get(self)));
524
+ }
525
+
526
+ /*
527
+ * call-seq:
528
+ * reader.value -> text
529
+ *
530
+ * Provide the text value of the node if present.
531
+ */
532
+ static VALUE
533
+ ruby_xml_reader_value(VALUE self)
534
+ {
535
+ return CSTR2RVAL(xmlTextReaderConstValue(ruby_xml_text_reader_get(self)));
536
+ }
537
+
538
+ /*
539
+ * call-seq:
540
+ * reader.prefix -> prefix
541
+ *
542
+ * Get a shorthand reference to the namespace associated with the node.
543
+ */
544
+ static VALUE
545
+ ruby_xml_reader_prefix(VALUE self)
546
+ {
547
+ return CSTR2RVAL(xmlTextReaderConstPrefix(ruby_xml_text_reader_get(self)));
548
+ }
549
+
550
+ /*
551
+ * call-seq:
552
+ * reader.depth -> depth
553
+ *
554
+ * Get the depth of the node in the tree.
555
+ */
556
+ static VALUE
557
+ ruby_xml_reader_depth(VALUE self)
558
+ {
559
+ return INT2FIX(xmlTextReaderDepth(ruby_xml_text_reader_get(self)));
560
+ }
561
+
562
+ /*
563
+ * call-seq:
564
+ * reader.quote_char -> char
565
+ *
566
+ * Get the quotation mark character used to enclose the value of an attribute,
567
+ * as an integer value (and -1 in case of error).
568
+ */
569
+ static VALUE
570
+ ruby_xml_reader_quote_char(VALUE self)
571
+ {
572
+ return INT2FIX(xmlTextReaderQuoteChar(ruby_xml_text_reader_get(self)));
573
+ }
574
+
575
+ /*
576
+ * call-seq:
577
+ * reader.standalone -> code
578
+ *
579
+ * Determine the standalone status of the document being read.
580
+ *
581
+ * Return 1 if the document was declared to be standalone, 0 if it was
582
+ * declared to be not standalone, or -1 if the document did not specify its
583
+ * standalone status or in case of error.
584
+ */
585
+ static VALUE
586
+ ruby_xml_reader_standalone(VALUE self)
587
+ {
588
+ return INT2FIX(xmlTextReaderStandalone(ruby_xml_text_reader_get(self)));
589
+ }
590
+
591
+ /*
592
+ * call-seq:
593
+ * reader.xml_lang -> value
594
+ *
595
+ * Get the xml:lang scope within which the node resides.
596
+ */
597
+ static VALUE
598
+ ruby_xml_reader_xml_lang(VALUE self)
599
+ {
600
+ return CSTR2RVAL(xmlTextReaderConstXmlLang(ruby_xml_text_reader_get(self)));
601
+ }
602
+
603
+ /*
604
+ * call-seq:
605
+ * reader.xml_version -> version
606
+ *
607
+ * Determine the XML version of the document being read.
608
+ */
609
+ static VALUE
610
+ ruby_xml_reader_xml_version(VALUE self)
611
+ {
612
+ return CSTR2RVAL(xmlTextReaderConstXmlVersion(ruby_xml_text_reader_get(self)));
613
+ }
614
+
615
+ /*
616
+ * call-seq:
617
+ * reader.has_attributes? -> bool
618
+ *
619
+ * Get whether the node has attributes.
620
+ */
621
+ static VALUE
622
+ ruby_xml_reader_has_attributes(VALUE self)
623
+ {
624
+ return xmlTextReaderHasAttributes(ruby_xml_text_reader_get(self)) ? Qtrue : Qfalse;
625
+ }
626
+
627
+ /*
628
+ * call-seq:
629
+ * reader.has_value? -> bool
630
+ *
631
+ * Get whether the node can have a text value.
632
+ */
633
+ static VALUE
634
+ ruby_xml_reader_has_value(VALUE self)
635
+ {
636
+ return xmlTextReaderHasValue(ruby_xml_text_reader_get(self)) ? Qtrue : Qfalse;
637
+ }
638
+
639
+ /*
640
+ * call-seq:
641
+ * reader[key] -> value
642
+ *
643
+ * Provide the value of the attribute with the specified index (if +key+ is an
644
+ * integer) or with the specified name (if +key+ is a string) relative to the
645
+ * containing element, as a string.
646
+ */
647
+ static VALUE
648
+ ruby_xml_reader_attribute(VALUE self, VALUE key)
649
+ {
650
+ xmlTextReaderPtr reader;
651
+ xmlChar *attr;
652
+
653
+ reader = ruby_xml_text_reader_get(self);
654
+
655
+ if (TYPE(key) == T_FIXNUM) {
656
+ attr = xmlTextReaderGetAttributeNo(reader, FIX2INT(key));
657
+ }
658
+ else {
659
+ attr = xmlTextReaderGetAttribute(reader, (const xmlChar *)RVAL2CSTR(key));
660
+ }
661
+ return CSTR2RVAL2(attr);
662
+ }
663
+
664
+ /*
665
+ * call-seq:
666
+ * reader.lookup_namespace(prefix) -> value
667
+ *
668
+ * Resolve a namespace prefix in the scope of the current element.
669
+ * To return the default namespace, specify nil as +prefix+.
670
+ */
671
+ static VALUE
672
+ ruby_xml_reader_lookup_namespace(VALUE self, VALUE prefix)
673
+ {
674
+ return CSTR2RVAL2(xmlTextReaderLookupNamespace(ruby_xml_text_reader_get(self), (const xmlChar *)RVAL2CSTR(prefix)));
675
+ }
676
+
677
+ /*
678
+ * call-seq:
679
+ * reader.expand -> node
680
+ *
681
+ * Read the contents of the current node and the full subtree. It then makes
682
+ * the subtree available until the next read call.
683
+ *
684
+ * Return an XML::Node object, or nil in case of error.
685
+ */
686
+ static VALUE
687
+ ruby_xml_reader_expand(VALUE self)
688
+ {
689
+ xmlNodePtr node;
690
+ xmlDocPtr doc;
691
+ xmlTextReaderPtr reader = ruby_xml_text_reader_get(self);
692
+ node = xmlTextReaderExpand(reader);
693
+
694
+ if (!node)
695
+ return Qnil;
696
+
697
+ /* Okay this is tricky. By accessing the returned node, we
698
+ take ownership of the reader's document. Thus we need to
699
+ tell the reader to not free it. Otherwise it will be
700
+ freed twice - once when the Ruby document wrapper goes
701
+ out of scope and once when the reader goes out of scope. */
702
+
703
+ xmlTextReaderPreserve(reader);
704
+ doc = xmlTextReaderCurrentDoc(reader);
705
+ ruby_xml_document_wrap(doc);
706
+
707
+ return ruby_xml_node2_wrap(cXMLNode, node);
708
+ }
709
+
710
+ #if LIBXML_VERSION >= 20618
711
+ /*
712
+ * call-seq:
713
+ * reader.byte_consumed -> value
714
+ *
715
+ * This method provides the current index of the parser used by the reader,
716
+ * relative to the start of the current entity.
717
+ */
718
+ static VALUE
719
+ ruby_xml_reader_byte_consumed(VALUE self)
720
+ {
721
+ return INT2NUM(xmlTextReaderByteConsumed(ruby_xml_text_reader_get(self)));
722
+ }
723
+ #endif
724
+
725
+ #if LIBXML_VERSION >= 20617
726
+ /*
727
+ * call-seq:
728
+ * reader.column_number -> number
729
+ *
730
+ * Provide the column number of the current parsing point.
731
+ */
732
+ static VALUE
733
+ ruby_xml_reader_column_number(VALUE self)
734
+ {
735
+ return INT2NUM(xmlTextReaderGetParserColumnNumber(ruby_xml_text_reader_get(self)));
736
+ }
737
+
738
+ /*
739
+ * call-seq:
740
+ * reader.line_number -> number
741
+ *
742
+ * Provide the line number of the current parsing point.
743
+ */
744
+ static VALUE
745
+ ruby_xml_reader_line_number(VALUE self)
746
+ {
747
+ return INT2NUM(xmlTextReaderGetParserLineNumber(ruby_xml_text_reader_get(self)));
748
+ }
749
+ #endif
750
+
751
+ /*
752
+ * call-seq:
753
+ * reader.default? -> bool
754
+ *
755
+ * Return whether an Attribute node was generated from the default value
756
+ * defined in the DTD or schema.
757
+ */
758
+ static VALUE
759
+ ruby_xml_reader_default(VALUE self)
760
+ {
761
+ return xmlTextReaderIsDefault(ruby_xml_text_reader_get(self)) ? Qtrue : Qfalse;
762
+ }
763
+
764
+ /*
765
+ * call-seq:
766
+ * reader.namespace_declaration? -> bool
767
+ *
768
+ * Determine whether the current node is a namespace declaration rather than a
769
+ * regular attribute.
770
+ */
771
+ static VALUE
772
+ ruby_xml_reader_namespace_declaration(VALUE self)
773
+ {
774
+ return xmlTextReaderIsNamespaceDecl(ruby_xml_text_reader_get(self)) ? Qtrue : Qfalse;
775
+ }
776
+
777
+ /*
778
+ * call-seq:
779
+ * reader.empty_element? -> bool
780
+ *
781
+ * Check if the current node is empty.
782
+ */
783
+ static VALUE
784
+ ruby_xml_reader_empty_element(VALUE self)
785
+ {
786
+ return xmlTextReaderIsEmptyElement(ruby_xml_text_reader_get(self)) ? Qtrue : Qfalse;
787
+ }
788
+
789
+ /*
790
+ * call-seq:
791
+ * reader.valid? -> bool
792
+ *
793
+ * Retrieve the validity status from the parser context.
794
+ */
795
+ static VALUE
796
+ ruby_xml_reader_valid(VALUE self)
797
+ {
798
+ return xmlTextReaderIsValid(ruby_xml_text_reader_get(self)) ? Qtrue : Qfalse;
799
+ }
800
+
801
+ /* Rdoc needs to know. */
802
+ #ifdef RDOC_NEVER_DEFINED
803
+ mLibXML = rb_define_module("LibXML");
804
+ mXML = rb_define_module_under(mLibXML, "XML");
805
+ #endif
806
+
807
+ void
808
+ ruby_init_xml_reader(void)
809
+ {
810
+ cXMLReader = rb_define_class_under(mXML, "Reader", rb_cObject);
811
+
812
+ rb_define_singleton_method(cXMLReader, "file", ruby_xml_reader_new_file, -1);
813
+ rb_define_singleton_method(cXMLReader, "io", ruby_xml_reader_new_io, -1);
814
+ rb_define_singleton_method(cXMLReader, "walker", ruby_xml_reader_new_walker, 1);
815
+ rb_define_alias(CLASS_OF(cXMLReader), "document", "walker");
816
+ rb_define_singleton_method(cXMLReader, "new", ruby_xml_reader_new_data, -1);
817
+ rb_define_alias(CLASS_OF(cXMLReader), "string", "new");
818
+
819
+ rb_define_method(cXMLReader, "close", ruby_xml_reader_close, 0);
820
+
821
+ rb_define_method(cXMLReader, "move_to_attribute", ruby_xml_reader_move_to_attr, 1);
822
+ rb_define_method(cXMLReader, "move_to_first_attribute", ruby_xml_reader_move_to_first_attr, 0);
823
+ rb_define_method(cXMLReader, "move_to_next_attribute", ruby_xml_reader_move_to_next_attr, 0);
824
+ rb_define_method(cXMLReader, "move_to_element", ruby_xml_reader_move_to_element, 0);
825
+ rb_define_method(cXMLReader, "next", ruby_xml_reader_next, 0);
826
+ rb_define_method(cXMLReader, "next_sibling", ruby_xml_reader_next_sibling, 0);
827
+ rb_define_method(cXMLReader, "read", ruby_xml_reader_read, 0);
828
+ rb_define_method(cXMLReader, "read_attribute_value", ruby_xml_reader_read_attr_value, 0);
829
+ rb_define_method(cXMLReader, "read_inner_xml", ruby_xml_reader_read_inner_xml, 0);
830
+ rb_define_method(cXMLReader, "read_outer_xml", ruby_xml_reader_read_outer_xml, 0);
831
+ rb_define_method(cXMLReader, "read_state", ruby_xml_reader_read_state, 0);
832
+ rb_define_method(cXMLReader, "read_string", ruby_xml_reader_read_string, 0);
833
+
834
+ rb_define_method(cXMLReader, "relax_ng_validate", ruby_xml_reader_relax_ng_validate, 1);
835
+ #if LIBXML_VERSION >= 20620
836
+ rb_define_method(cXMLReader, "schema_validate", ruby_xml_reader_schema_validate, 1);
837
+ #endif
838
+
839
+ rb_define_method(cXMLReader, "node_type", ruby_xml_reader_node_type, 0);
840
+ rb_define_method(cXMLReader, "normalization", ruby_xml_reader_normalization, 0);
841
+ rb_define_method(cXMLReader, "attribute_count", ruby_xml_reader_attr_count, 0);
842
+ rb_define_method(cXMLReader, "name", ruby_xml_reader_name, 0);
843
+ rb_define_method(cXMLReader, "local_name", ruby_xml_reader_local_name, 0);
844
+ rb_define_method(cXMLReader, "encoding", ruby_xml_reader_encoding, 0);
845
+ rb_define_method(cXMLReader, "base_uri", ruby_xml_reader_base_uri, 0);
846
+ rb_define_method(cXMLReader, "namespace_uri", ruby_xml_reader_namespace_uri, 0);
847
+ rb_define_method(cXMLReader, "xml_lang", ruby_xml_reader_xml_lang, 0);
848
+ rb_define_method(cXMLReader, "xml_version", ruby_xml_reader_xml_version, 0);
849
+ rb_define_method(cXMLReader, "prefix", ruby_xml_reader_prefix, 0);
850
+ rb_define_method(cXMLReader, "depth", ruby_xml_reader_depth, 0);
851
+ rb_define_method(cXMLReader, "quote_char", ruby_xml_reader_quote_char, 0);
852
+ rb_define_method(cXMLReader, "standalone", ruby_xml_reader_standalone, 0);
853
+
854
+ rb_define_method(cXMLReader, "has_attributes?", ruby_xml_reader_has_attributes, 0);
855
+ rb_define_method(cXMLReader, "[]", ruby_xml_reader_attribute, 1);
856
+ rb_define_method(cXMLReader, "has_value?", ruby_xml_reader_has_value, 0);
857
+ rb_define_method(cXMLReader, "value", ruby_xml_reader_value, 0);
858
+
859
+ rb_define_method(cXMLReader, "lookup_namespace", ruby_xml_reader_lookup_namespace, 1);
860
+ rb_define_method(cXMLReader, "expand", ruby_xml_reader_expand, 0);
861
+
862
+ #if LIBXML_VERSION >= 20618
863
+ rb_define_method(cXMLReader, "byte_consumed", ruby_xml_reader_byte_consumed, 0);
864
+ #endif
865
+ #if LIBXML_VERSION >= 20617
866
+ rb_define_method(cXMLReader, "column_number", ruby_xml_reader_column_number, 0);
867
+ rb_define_method(cXMLReader, "line_number", ruby_xml_reader_line_number, 0);
868
+ #endif
869
+ rb_define_method(cXMLReader, "default?", ruby_xml_reader_default, 0);
870
+ rb_define_method(cXMLReader, "empty_element?", ruby_xml_reader_empty_element, 0);
871
+ rb_define_method(cXMLReader, "namespace_declaration?", ruby_xml_reader_namespace_declaration, 0);
872
+ rb_define_method(cXMLReader, "valid?", ruby_xml_reader_valid, 0);
873
+
874
+ rb_define_const(cXMLReader, "LOADDTD", INT2FIX(XML_PARSER_LOADDTD));
875
+ rb_define_const(cXMLReader, "DEFAULTATTRS", INT2FIX(XML_PARSER_DEFAULTATTRS));
876
+ rb_define_const(cXMLReader, "VALIDATE", INT2FIX(XML_PARSER_VALIDATE));
877
+ rb_define_const(cXMLReader, "SUBST_ENTITIES", INT2FIX(XML_PARSER_SUBST_ENTITIES));
878
+
879
+ rb_define_const(cXMLReader, "SEVERITY_VALIDITY_WARNING", INT2FIX(XML_PARSER_SEVERITY_VALIDITY_WARNING));
880
+ rb_define_const(cXMLReader, "SEVERITY_VALIDITY_ERROR", INT2FIX(XML_PARSER_SEVERITY_VALIDITY_ERROR));
881
+ rb_define_const(cXMLReader, "SEVERITY_WARNING", INT2FIX(XML_PARSER_SEVERITY_WARNING));
882
+ rb_define_const(cXMLReader, "SEVERITY_ERROR", INT2FIX(XML_PARSER_SEVERITY_ERROR));
883
+
884
+ rb_define_const(cXMLReader, "TYPE_NONE", INT2FIX(XML_READER_TYPE_NONE));
885
+ rb_define_const(cXMLReader, "TYPE_ELEMENT", INT2FIX(XML_READER_TYPE_ELEMENT));
886
+ rb_define_const(cXMLReader, "TYPE_ATTRIBUTE", INT2FIX(XML_READER_TYPE_ATTRIBUTE));
887
+ rb_define_const(cXMLReader, "TYPE_TEXT", INT2FIX(XML_READER_TYPE_TEXT));
888
+ rb_define_const(cXMLReader, "TYPE_CDATA", INT2FIX(XML_READER_TYPE_CDATA));
889
+ rb_define_const(cXMLReader, "TYPE_ENTITY_REFERENCE", INT2FIX(XML_READER_TYPE_ENTITY_REFERENCE));
890
+ rb_define_const(cXMLReader, "TYPE_ENTITY", INT2FIX(XML_READER_TYPE_ENTITY));
891
+ rb_define_const(cXMLReader, "TYPE_PROCESSING_INSTRUCTION", INT2FIX(XML_READER_TYPE_PROCESSING_INSTRUCTION));
892
+ rb_define_const(cXMLReader, "TYPE_COMMENT", INT2FIX(XML_READER_TYPE_COMMENT));
893
+ rb_define_const(cXMLReader, "TYPE_DOCUMENT", INT2FIX(XML_READER_TYPE_DOCUMENT));
894
+ rb_define_const(cXMLReader, "TYPE_DOCUMENT_TYPE", INT2FIX(XML_READER_TYPE_DOCUMENT_TYPE));
895
+ rb_define_const(cXMLReader, "TYPE_DOCUMENT_FRAGMENT", INT2FIX(XML_READER_TYPE_DOCUMENT_FRAGMENT));
896
+ rb_define_const(cXMLReader, "TYPE_NOTATION", INT2FIX(XML_READER_TYPE_NOTATION));
897
+ rb_define_const(cXMLReader, "TYPE_WHITESPACE", INT2FIX(XML_READER_TYPE_WHITESPACE));
898
+ rb_define_const(cXMLReader, "TYPE_SIGNIFICANT_WHITESPACE", INT2FIX(XML_READER_TYPE_SIGNIFICANT_WHITESPACE));
899
+ rb_define_const(cXMLReader, "TYPE_END_ELEMENT", INT2FIX(XML_READER_TYPE_END_ELEMENT));
900
+ rb_define_const(cXMLReader, "TYPE_END_ENTITY", INT2FIX(XML_READER_TYPE_END_ENTITY));
901
+ rb_define_const(cXMLReader, "TYPE_XML_DECLARATION", INT2FIX(XML_READER_TYPE_XML_DECLARATION));
902
+
903
+ /* Read states */
904
+ rb_define_const(cXMLReader, "MODE_INITIAL", INT2FIX(XML_TEXTREADER_MODE_INITIAL));
905
+ rb_define_const(cXMLReader, "MODE_INTERACTIVE", INT2FIX(XML_TEXTREADER_MODE_INTERACTIVE));
906
+ rb_define_const(cXMLReader, "MODE_ERROR", INT2FIX(XML_TEXTREADER_MODE_ERROR));
907
+ rb_define_const(cXMLReader, "MODE_EOF", INT2FIX(XML_TEXTREADER_MODE_EOF));
908
+ rb_define_const(cXMLReader, "MODE_CLOSED", INT2FIX(XML_TEXTREADER_MODE_CLOSED));
909
+ rb_define_const(cXMLReader, "MODE_READING", INT2FIX(XML_TEXTREADER_MODE_READING));
910
+ }