libxml-ruby 0.9.3-x86-mswin32-60 → 0.9.4-x86-mswin32-60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,893 +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
- 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
-
60
- static VALUE
61
- rxml_reader_new(VALUE class, xmlTextReaderPtr reader)
62
- {
63
- return Data_Wrap_Struct(class, NULL, xmlFreeTextReader, reader);
64
- }
65
-
66
- static xmlTextReaderPtr
67
- rxml_text_reader_get(VALUE obj)
68
- {
69
- xmlTextReaderPtr ptr;
70
- Data_Get_Struct(obj, xmlTextReader, ptr);
71
- return ptr;
72
- }
73
-
74
- /*
75
- * call-seq:
76
- * XML::Reader.file(path, encoding=nil, options=0) -> reader
77
- *
78
- * Parse an XML file from the filesystem or the network. The parsing flags
79
- * options are a combination of xmlParserOption.
80
- */
81
- static VALUE
82
- rxml_reader_new_file(int argc, VALUE *argv, VALUE self)
83
- {
84
- xmlTextReaderPtr reader;
85
- VALUE path, encoding, options;
86
-
87
- rb_scan_args(argc, argv, "12", &path, &encoding, &options);
88
-
89
- reader = xmlReaderForFile(RVAL2CSTR(path),
90
- NIL_P(encoding) ? NULL : RVAL2CSTR(encoding),
91
- NIL_P(options) ? 0 : FIX2INT(options));
92
- if (reader == NULL)
93
- rb_raise(rb_eRuntimeError,
94
- "cannot create text reader for given XML file at path '%s'",
95
- RVAL2CSTR(path));
96
-
97
- return rxml_reader_new(self, reader);
98
- }
99
-
100
- /*
101
- * call-seq:
102
- * XML::Reader.io(io, url=nil, encoding=nil, options=0) -> reader
103
- *
104
- * Parse an XML file from a file handle. The parsing flags options are
105
- * a combination of xmlParserOption.
106
- */
107
- static VALUE
108
- rxml_reader_new_io(int argc, VALUE *argv, VALUE self)
109
- {
110
- xmlTextReaderPtr reader;
111
- VALUE io, url, encoding, options;
112
-
113
- rb_scan_args(argc, argv, "13", &io, &url, &encoding, &options);
114
-
115
- reader = xmlReaderForIO((xmlInputReadCallback) rxml_read_callback, NULL, io,
116
- NIL_P(url) ? NULL : RVAL2CSTR(url),
117
- NIL_P(encoding) ? NULL : RVAL2CSTR(encoding),
118
- NIL_P(options) ? 0 : FIX2INT(options));
119
- if (reader == NULL)
120
- rb_raise(rb_eRuntimeError, "cannot create text reader for given stream");
121
-
122
- return rxml_reader_new(self, reader);
123
- }
124
-
125
- /*
126
- * call-seq:
127
- * XML::Reader.walker(doc) -> reader
128
- * XML::Reader.document(doc) -> reader
129
- *
130
- * Create an XML text reader for a preparsed document.
131
- */
132
- VALUE
133
- rxml_reader_new_walker(VALUE self, VALUE doc)
134
- {
135
- xmlDocPtr xdoc;
136
- xmlTextReaderPtr reader;
137
-
138
- Data_Get_Struct(doc, xmlDoc, xdoc);
139
-
140
- reader = xmlReaderWalker(xdoc);
141
- if (reader == NULL)
142
- rb_raise(rb_eRuntimeError, "cannot create text reader for given document");
143
-
144
- return rxml_reader_new(self, reader);
145
- }
146
-
147
- /*
148
- * call-seq:
149
- * XML::Reader.new(data, url=nil, encoding=nil, options=0) -> reader
150
- * XML::Reader.string(data, url=nil, encoding=nil, options=0) -> reader
151
- *
152
- * Create an XML text reader for an XML in-memory document. The parsing flags
153
- * options are a combination of xmlParserOption.
154
- */
155
- static VALUE
156
- rxml_reader_new_data(int argc, VALUE *argv, VALUE self)
157
- {
158
- xmlTextReaderPtr reader;
159
- VALUE data, url, encoding, options;
160
- char *c_data;
161
-
162
- rb_scan_args(argc, argv, "13", &data, &url, &encoding, &options);
163
-
164
- c_data = RVAL2CSTR(data);
165
- reader = xmlReaderForMemory(c_data,
166
- strlen(c_data),
167
- NIL_P(url) ? NULL : RVAL2CSTR(url),
168
- NIL_P(encoding) ? NULL : RVAL2CSTR(encoding),
169
- NIL_P(options) ? 0 : FIX2INT(options));
170
- if (reader == NULL)
171
- rb_raise(rb_eRuntimeError, "cannot create text reader for given data");
172
-
173
- return rxml_reader_new(self, reader);
174
- }
175
-
176
- /*
177
- * call-seq:
178
- * parser.close -> code
179
- *
180
- * This method releases any resources allocated by the current instance
181
- * changes the state to Closed and close any underlying input.
182
- */
183
- static VALUE
184
- rxml_reader_close(VALUE self)
185
- {
186
- return INT2FIX(xmlTextReaderClose(rxml_text_reader_get(self)));
187
- }
188
-
189
- /*
190
- * call-seq:
191
- * parser.move_to_attribute(val) -> code
192
- *
193
- * Move the position of the current instance to the attribute with the
194
- * specified index (if +val+ is an integer) or name (if +val+ is a string)
195
- * relative to the containing element.
196
- */
197
- static VALUE
198
- rxml_reader_move_to_attr(VALUE self, VALUE val)
199
- {
200
- xmlTextReaderPtr reader;
201
- int ret;
202
-
203
- reader = rxml_text_reader_get(self);
204
-
205
- if (TYPE(val) == T_FIXNUM) {
206
- ret = xmlTextReaderMoveToAttributeNo(reader, FIX2INT(val));
207
- }
208
- else {
209
- ret = xmlTextReaderMoveToAttribute(reader, (const xmlChar *)RVAL2CSTR(val));
210
- }
211
-
212
- return INT2FIX(ret);
213
- }
214
-
215
- /*
216
- * call-seq:
217
- * reader.move_to_first_attribute -> code
218
- *
219
- * Move the position of the current instance to the first attribute associated
220
- * with the current node.
221
- */
222
- static VALUE
223
- rxml_reader_move_to_first_attr(VALUE self)
224
- {
225
- return INT2FIX(xmlTextReaderMoveToFirstAttribute(rxml_text_reader_get(self)));
226
- }
227
-
228
- /*
229
- * call-seq:
230
- * reader.move_to_next_attribute -> code
231
- *
232
- * Move the position of the current instance to the next attribute associated
233
- * with the current node.
234
- */
235
- static VALUE
236
- rxml_reader_move_to_next_attr(VALUE self)
237
- {
238
- return INT2FIX(xmlTextReaderMoveToNextAttribute(rxml_text_reader_get(self)));
239
- }
240
-
241
- /*
242
- * call-seq:
243
- * reader.move_to_element -> code
244
- *
245
- * Move the position of the current instance to the node that contains the
246
- * current attribute node.
247
- */
248
- static VALUE
249
- rxml_reader_move_to_element(VALUE self)
250
- {
251
- return INT2FIX(xmlTextReaderMoveToElement(rxml_text_reader_get(self)));
252
- }
253
-
254
- /*
255
- * call-seq:
256
- * reader.next -> code
257
- *
258
- * Skip to the node following the current one in document order while avoiding
259
- * the subtree if any.
260
- */
261
- static VALUE
262
- rxml_reader_next(VALUE self)
263
- {
264
- return INT2FIX(xmlTextReaderNext(rxml_text_reader_get(self)));
265
- }
266
-
267
- /*
268
- * call-seq:
269
- * reader.next_sibling -> code
270
- *
271
- * Skip to the node following the current one in document order while avoiding
272
- * the subtree if any. Currently implemented only for Readers built on a
273
- * document.
274
- */
275
- static VALUE
276
- rxml_reader_next_sibling(VALUE self)
277
- {
278
- return INT2FIX(xmlTextReaderNextSibling(rxml_text_reader_get(self)));
279
- }
280
-
281
- /*
282
- * call-seq:
283
- * reader.node_type -> type
284
- *
285
- * Get the node type of the current node. Reference:
286
- * http://dotgnu.org/pnetlib-doc/System/Xml/XmlNodeType.html
287
- */
288
- static VALUE
289
- rxml_reader_node_type(VALUE self)
290
- {
291
- return INT2FIX(xmlTextReaderNodeType(rxml_text_reader_get(self)));
292
- }
293
-
294
- /*
295
- * call-seq:
296
- * reader.normalization -> value
297
- *
298
- * The value indicating whether to normalize white space and attribute values.
299
- * Since attribute value and end of line normalizations are a MUST in the XML
300
- * specification only the value true is accepted. The broken bahaviour of
301
- * accepting out of range character entities like &#0; is of course not
302
- * supported either.
303
- *
304
- * Return 1 or -1 in case of error.
305
- */
306
- static VALUE
307
- rxml_reader_normalization(VALUE self)
308
- {
309
- return INT2FIX(xmlTextReaderNormalization(rxml_text_reader_get(self)));
310
- }
311
-
312
- /*
313
- * call-seq:
314
- * reader.read -> code
315
- *
316
- * Move the position of the current instance to the next node in the stream,
317
- * exposing its properties.
318
- *
319
- * Return 1 if the node was read successfully, 0 if there is no more nodes to
320
- * read, or -1 in case of error.
321
- */
322
- static VALUE
323
- rxml_reader_read(VALUE self)
324
- {
325
- return INT2FIX(xmlTextReaderRead(rxml_text_reader_get(self)));
326
- }
327
-
328
- /*
329
- * call-seq:
330
- * reader.read_attribute_value -> code
331
- *
332
- * Parse an attribute value into one or more Text and EntityReference nodes.
333
- *
334
- * Return 1 in case of success, 0 if the reader was not positionned on an
335
- * attribute node or all the attribute values have been read, or -1 in case of
336
- * error.
337
- */
338
- static VALUE
339
- rxml_reader_read_attr_value(VALUE self)
340
- {
341
- return INT2FIX(xmlTextReaderReadAttributeValue(rxml_text_reader_get(self)));
342
- }
343
-
344
- /*
345
- * call-seq:
346
- * reader.read_inner_xml -> data
347
- *
348
- * Read the contents of the current node, including child nodes and markup.
349
- *
350
- * Return a string containing the XML content, or nil if the current node is
351
- * neither an element nor attribute, or has no child nodes.
352
- */
353
- static VALUE
354
- rxml_reader_read_inner_xml(VALUE self)
355
- {
356
- return CSTR2RVAL2(xmlTextReaderReadInnerXml(rxml_text_reader_get(self)));
357
- }
358
-
359
- /*
360
- * call-seq:
361
- * reader.read_outer_xml -> data
362
- *
363
- * Read the contents of the current node, including child nodes and markup.
364
- *
365
- * Return a string containing the XML content, or nil if the current node is
366
- * neither an element nor attribute, or has no child nodes.
367
- */
368
- static VALUE
369
- rxml_reader_read_outer_xml(VALUE self)
370
- {
371
- return CSTR2RVAL2(xmlTextReaderReadOuterXml(rxml_text_reader_get(self)));
372
- }
373
-
374
- /*
375
- * call-seq:
376
- * reader.read_state -> state
377
- *
378
- * Get the read state of the reader.
379
- */
380
- static VALUE
381
- rxml_reader_read_state(VALUE self)
382
- {
383
- return INT2FIX(xmlTextReaderReadState(rxml_text_reader_get(self)));
384
- }
385
-
386
- /*
387
- * call-seq:
388
- * reader.read_string -> string
389
- *
390
- * Read the contents of an element or a text node as a string.
391
- *
392
- * Return a string containing the contents of the Element or Text node, or nil
393
- * if the reader is positioned on any other type of node.
394
- */
395
- static VALUE
396
- rxml_reader_read_string(VALUE self)
397
- {
398
- return CSTR2RVAL2(xmlTextReaderReadString(rxml_text_reader_get(self)));
399
- }
400
-
401
- /*
402
- * call-seq:
403
- * reader.relax_ng_validate(rng) -> code
404
- *
405
- * Use RelaxNG to validate the document as it is processed. Activation is only
406
- * possible before the first read. If +rng+ is nil, the RelaxNG validation is
407
- * desactivated.
408
- *
409
- * Return 0 in case the RelaxNG validation could be (des)activated and -1 in
410
- * case of error.
411
- */
412
- static VALUE
413
- rxml_reader_relax_ng_validate(VALUE self, VALUE rng)
414
- {
415
- return INT2FIX(xmlTextReaderRelaxNGValidate(rxml_text_reader_get(self), NIL_P(rng) ? NULL : RVAL2CSTR(rng)));
416
- }
417
-
418
- #if LIBXML_VERSION >= 20620
419
- /*
420
- * call-seq:
421
- * reader.schema_validate(schema) -> code
422
- *
423
- * Use W3C XSD schema to validate the document as it is processed. Activation
424
- * is only possible before the first read. If +schema+ is nil, then XML Schema
425
- * validation is desactivated.
426
- *
427
- * Return 0 in case the schemas validation could be (de)activated and -1 in
428
- * case of error.
429
- */
430
- static VALUE
431
- rxml_reader_schema_validate(VALUE self, VALUE xsd)
432
- {
433
- return INT2FIX(xmlTextReaderSchemaValidate(rxml_text_reader_get(self), NIL_P(xsd) ? NULL : RVAL2CSTR(xsd)));
434
- }
435
- #endif
436
-
437
- /*
438
- * call-seq:
439
- * reader.name -> name
440
- *
441
- * Return the qualified name of the node.
442
- */
443
- static VALUE
444
- rxml_reader_name(VALUE self)
445
- {
446
- return CSTR2RVAL(xmlTextReaderConstName(rxml_text_reader_get(self)));
447
- }
448
-
449
- /*
450
- * call-seq:
451
- * reader.local_name -> name
452
- *
453
- * Return the local name of the node.
454
- */
455
- static VALUE
456
- rxml_reader_local_name(VALUE self)
457
- {
458
- return CSTR2RVAL(xmlTextReaderConstLocalName(rxml_text_reader_get(self)));
459
- }
460
-
461
- /*
462
- * call-seq:
463
- * reader.attribute_count -> count
464
- *
465
- * Provide the number of attributes of the current node.
466
- */
467
- static VALUE
468
- rxml_reader_attr_count(VALUE self)
469
- {
470
- return INT2FIX(xmlTextReaderAttributeCount(rxml_text_reader_get(self)));
471
- }
472
-
473
- /*
474
- * call-seq:
475
- * reader.encoding -> encoding
476
- *
477
- * Determine the encoding of the document being read.
478
- */
479
- static VALUE
480
- rxml_reader_encoding(VALUE self)
481
- {
482
- return CSTR2RVAL(xmlTextReaderConstEncoding(rxml_text_reader_get(self)));
483
- }
484
-
485
- /*
486
- * call-seq:
487
- * reader.base_uri -> URI
488
- *
489
- * Determine the base URI of the node.
490
- */
491
- static VALUE
492
- rxml_reader_base_uri(VALUE self)
493
- {
494
- return CSTR2RVAL(xmlTextReaderConstBaseUri(rxml_text_reader_get(self)));
495
- }
496
-
497
- /*
498
- * call-seq:
499
- * reader.namespace_uri -> URI
500
- *
501
- * Determine the namespace URI of the node.
502
- */
503
- static VALUE
504
- rxml_reader_namespace_uri(VALUE self)
505
- {
506
- return CSTR2RVAL(xmlTextReaderConstNamespaceUri(rxml_text_reader_get(self)));
507
- }
508
-
509
- /*
510
- * call-seq:
511
- * reader.value -> text
512
- *
513
- * Provide the text value of the node if present.
514
- */
515
- static VALUE
516
- rxml_reader_value(VALUE self)
517
- {
518
- return CSTR2RVAL(xmlTextReaderConstValue(rxml_text_reader_get(self)));
519
- }
520
-
521
- /*
522
- * call-seq:
523
- * reader.prefix -> prefix
524
- *
525
- * Get a shorthand reference to the namespace associated with the node.
526
- */
527
- static VALUE
528
- rxml_reader_prefix(VALUE self)
529
- {
530
- return CSTR2RVAL(xmlTextReaderConstPrefix(rxml_text_reader_get(self)));
531
- }
532
-
533
- /*
534
- * call-seq:
535
- * reader.depth -> depth
536
- *
537
- * Get the depth of the node in the tree.
538
- */
539
- static VALUE
540
- rxml_reader_depth(VALUE self)
541
- {
542
- return INT2FIX(xmlTextReaderDepth(rxml_text_reader_get(self)));
543
- }
544
-
545
- /*
546
- * call-seq:
547
- * reader.quote_char -> char
548
- *
549
- * Get the quotation mark character used to enclose the value of an attribute,
550
- * as an integer value (and -1 in case of error).
551
- */
552
- static VALUE
553
- rxml_reader_quote_char(VALUE self)
554
- {
555
- return INT2FIX(xmlTextReaderQuoteChar(rxml_text_reader_get(self)));
556
- }
557
-
558
- /*
559
- * call-seq:
560
- * reader.standalone -> code
561
- *
562
- * Determine the standalone status of the document being read.
563
- *
564
- * Return 1 if the document was declared to be standalone, 0 if it was
565
- * declared to be not standalone, or -1 if the document did not specify its
566
- * standalone status or in case of error.
567
- */
568
- static VALUE
569
- rxml_reader_standalone(VALUE self)
570
- {
571
- return INT2FIX(xmlTextReaderStandalone(rxml_text_reader_get(self)));
572
- }
573
-
574
- /*
575
- * call-seq:
576
- * reader.xml_lang -> value
577
- *
578
- * Get the xml:lang scope within which the node resides.
579
- */
580
- static VALUE
581
- rxml_reader_xml_lang(VALUE self)
582
- {
583
- return CSTR2RVAL(xmlTextReaderConstXmlLang(rxml_text_reader_get(self)));
584
- }
585
-
586
- /*
587
- * call-seq:
588
- * reader.xml_version -> version
589
- *
590
- * Determine the XML version of the document being read.
591
- */
592
- static VALUE
593
- rxml_reader_xml_version(VALUE self)
594
- {
595
- return CSTR2RVAL(xmlTextReaderConstXmlVersion(rxml_text_reader_get(self)));
596
- }
597
-
598
- /*
599
- * call-seq:
600
- * reader.has_attributes? -> bool
601
- *
602
- * Get whether the node has attributes.
603
- */
604
- static VALUE
605
- rxml_reader_has_attributes(VALUE self)
606
- {
607
- return xmlTextReaderHasAttributes(rxml_text_reader_get(self)) ? Qtrue : Qfalse;
608
- }
609
-
610
- /*
611
- * call-seq:
612
- * reader.has_value? -> bool
613
- *
614
- * Get whether the node can have a text value.
615
- */
616
- static VALUE
617
- rxml_reader_has_value(VALUE self)
618
- {
619
- return xmlTextReaderHasValue(rxml_text_reader_get(self)) ? Qtrue : Qfalse;
620
- }
621
-
622
- /*
623
- * call-seq:
624
- * reader[key] -> value
625
- *
626
- * Provide the value of the attribute with the specified index (if +key+ is an
627
- * integer) or with the specified name (if +key+ is a string) relative to the
628
- * containing element, as a string.
629
- */
630
- static VALUE
631
- rxml_reader_attribute(VALUE self, VALUE key)
632
- {
633
- xmlTextReaderPtr reader;
634
- xmlChar *attr;
635
-
636
- reader = rxml_text_reader_get(self);
637
-
638
- if (TYPE(key) == T_FIXNUM) {
639
- attr = xmlTextReaderGetAttributeNo(reader, FIX2INT(key));
640
- }
641
- else {
642
- attr = xmlTextReaderGetAttribute(reader, (const xmlChar *)RVAL2CSTR(key));
643
- }
644
- return CSTR2RVAL2(attr);
645
- }
646
-
647
- /*
648
- * call-seq:
649
- * reader.lookup_namespace(prefix) -> value
650
- *
651
- * Resolve a namespace prefix in the scope of the current element.
652
- * To return the default namespace, specify nil as +prefix+.
653
- */
654
- static VALUE
655
- rxml_reader_lookup_namespace(VALUE self, VALUE prefix)
656
- {
657
- return CSTR2RVAL2(xmlTextReaderLookupNamespace(rxml_text_reader_get(self), (const xmlChar *)RVAL2CSTR(prefix)));
658
- }
659
-
660
- /*
661
- * call-seq:
662
- * reader.expand -> node
663
- *
664
- * Read the contents of the current node and the full subtree. It then makes
665
- * the subtree available until the next read call.
666
- *
667
- * Return an XML::Node object, or nil in case of error.
668
- */
669
- static VALUE
670
- rxml_reader_expand(VALUE self)
671
- {
672
- xmlNodePtr node;
673
- xmlDocPtr doc;
674
- xmlTextReaderPtr reader = rxml_text_reader_get(self);
675
- node = xmlTextReaderExpand(reader);
676
-
677
- if (!node)
678
- return Qnil;
679
-
680
- /* Okay this is tricky. By accessing the returned node, we
681
- take ownership of the reader's document. Thus we need to
682
- tell the reader to not free it. Otherwise it will be
683
- freed twice - once when the Ruby document wrapper goes
684
- out of scope and once when the reader goes out of scope. */
685
-
686
- xmlTextReaderPreserve(reader);
687
- doc = xmlTextReaderCurrentDoc(reader);
688
- rxml_document_wrap(doc);
689
-
690
- return rxml_node2_wrap(cXMLNode, node);
691
- }
692
-
693
- #if LIBXML_VERSION >= 20618
694
- /*
695
- * call-seq:
696
- * reader.byte_consumed -> value
697
- *
698
- * This method provides the current index of the parser used by the reader,
699
- * relative to the start of the current entity.
700
- */
701
- static VALUE
702
- rxml_reader_byte_consumed(VALUE self)
703
- {
704
- return INT2NUM(xmlTextReaderByteConsumed(rxml_text_reader_get(self)));
705
- }
706
- #endif
707
-
708
- #if LIBXML_VERSION >= 20617
709
- /*
710
- * call-seq:
711
- * reader.column_number -> number
712
- *
713
- * Provide the column number of the current parsing point.
714
- */
715
- static VALUE
716
- rxml_reader_column_number(VALUE self)
717
- {
718
- return INT2NUM(xmlTextReaderGetParserColumnNumber(rxml_text_reader_get(self)));
719
- }
720
-
721
- /*
722
- * call-seq:
723
- * reader.line_number -> number
724
- *
725
- * Provide the line number of the current parsing point.
726
- */
727
- static VALUE
728
- rxml_reader_line_number(VALUE self)
729
- {
730
- return INT2NUM(xmlTextReaderGetParserLineNumber(rxml_text_reader_get(self)));
731
- }
732
- #endif
733
-
734
- /*
735
- * call-seq:
736
- * reader.default? -> bool
737
- *
738
- * Return whether an Attribute node was generated from the default value
739
- * defined in the DTD or schema.
740
- */
741
- static VALUE
742
- rxml_reader_default(VALUE self)
743
- {
744
- return xmlTextReaderIsDefault(rxml_text_reader_get(self)) ? Qtrue : Qfalse;
745
- }
746
-
747
- /*
748
- * call-seq:
749
- * reader.namespace_declaration? -> bool
750
- *
751
- * Determine whether the current node is a namespace declaration rather than a
752
- * regular attribute.
753
- */
754
- static VALUE
755
- rxml_reader_namespace_declaration(VALUE self)
756
- {
757
- return xmlTextReaderIsNamespaceDecl(rxml_text_reader_get(self)) ? Qtrue : Qfalse;
758
- }
759
-
760
- /*
761
- * call-seq:
762
- * reader.empty_element? -> bool
763
- *
764
- * Check if the current node is empty.
765
- */
766
- static VALUE
767
- rxml_reader_empty_element(VALUE self)
768
- {
769
- return xmlTextReaderIsEmptyElement(rxml_text_reader_get(self)) ? Qtrue : Qfalse;
770
- }
771
-
772
- /*
773
- * call-seq:
774
- * reader.valid? -> bool
775
- *
776
- * Retrieve the validity status from the parser context.
777
- */
778
- static VALUE
779
- rxml_reader_valid(VALUE self)
780
- {
781
- return xmlTextReaderIsValid(rxml_text_reader_get(self)) ? Qtrue : Qfalse;
782
- }
783
-
784
- /* Rdoc needs to know. */
785
- #ifdef RDOC_NEVER_DEFINED
786
- mLibXML = rb_define_module("LibXML");
787
- mXML = rb_define_module_under(mLibXML, "XML");
788
- #endif
789
-
790
- void
791
- ruby_init_xml_reader(void)
792
- {
793
- cXMLReader = rb_define_class_under(mXML, "Reader", rb_cObject);
794
-
795
- rb_define_singleton_method(cXMLReader, "file", rxml_reader_new_file, -1);
796
- rb_define_singleton_method(cXMLReader, "io", rxml_reader_new_io, -1);
797
- rb_define_singleton_method(cXMLReader, "walker", rxml_reader_new_walker, 1);
798
- rb_define_alias(CLASS_OF(cXMLReader), "document", "walker");
799
- rb_define_singleton_method(cXMLReader, "new", rxml_reader_new_data, -1);
800
- rb_define_alias(CLASS_OF(cXMLReader), "string", "new");
801
-
802
- rb_define_method(cXMLReader, "close", rxml_reader_close, 0);
803
-
804
- rb_define_method(cXMLReader, "move_to_attribute", rxml_reader_move_to_attr, 1);
805
- rb_define_method(cXMLReader, "move_to_first_attribute", rxml_reader_move_to_first_attr, 0);
806
- rb_define_method(cXMLReader, "move_to_next_attribute", rxml_reader_move_to_next_attr, 0);
807
- rb_define_method(cXMLReader, "move_to_element", rxml_reader_move_to_element, 0);
808
- rb_define_method(cXMLReader, "next", rxml_reader_next, 0);
809
- rb_define_method(cXMLReader, "next_sibling", rxml_reader_next_sibling, 0);
810
- rb_define_method(cXMLReader, "read", rxml_reader_read, 0);
811
- rb_define_method(cXMLReader, "read_attribute_value", rxml_reader_read_attr_value, 0);
812
- rb_define_method(cXMLReader, "read_inner_xml", rxml_reader_read_inner_xml, 0);
813
- rb_define_method(cXMLReader, "read_outer_xml", rxml_reader_read_outer_xml, 0);
814
- rb_define_method(cXMLReader, "read_state", rxml_reader_read_state, 0);
815
- rb_define_method(cXMLReader, "read_string", rxml_reader_read_string, 0);
816
-
817
- rb_define_method(cXMLReader, "relax_ng_validate", rxml_reader_relax_ng_validate, 1);
818
- #if LIBXML_VERSION >= 20620
819
- rb_define_method(cXMLReader, "schema_validate", rxml_reader_schema_validate, 1);
820
- #endif
821
-
822
- rb_define_method(cXMLReader, "node_type", rxml_reader_node_type, 0);
823
- rb_define_method(cXMLReader, "normalization", rxml_reader_normalization, 0);
824
- rb_define_method(cXMLReader, "attribute_count", rxml_reader_attr_count, 0);
825
- rb_define_method(cXMLReader, "name", rxml_reader_name, 0);
826
- rb_define_method(cXMLReader, "local_name", rxml_reader_local_name, 0);
827
- rb_define_method(cXMLReader, "encoding", rxml_reader_encoding, 0);
828
- rb_define_method(cXMLReader, "base_uri", rxml_reader_base_uri, 0);
829
- rb_define_method(cXMLReader, "namespace_uri", rxml_reader_namespace_uri, 0);
830
- rb_define_method(cXMLReader, "xml_lang", rxml_reader_xml_lang, 0);
831
- rb_define_method(cXMLReader, "xml_version", rxml_reader_xml_version, 0);
832
- rb_define_method(cXMLReader, "prefix", rxml_reader_prefix, 0);
833
- rb_define_method(cXMLReader, "depth", rxml_reader_depth, 0);
834
- rb_define_method(cXMLReader, "quote_char", rxml_reader_quote_char, 0);
835
- rb_define_method(cXMLReader, "standalone", rxml_reader_standalone, 0);
836
-
837
- rb_define_method(cXMLReader, "has_attributes?", rxml_reader_has_attributes, 0);
838
- rb_define_method(cXMLReader, "[]", rxml_reader_attribute, 1);
839
- rb_define_method(cXMLReader, "has_value?", rxml_reader_has_value, 0);
840
- rb_define_method(cXMLReader, "value", rxml_reader_value, 0);
841
-
842
- rb_define_method(cXMLReader, "lookup_namespace", rxml_reader_lookup_namespace, 1);
843
- rb_define_method(cXMLReader, "expand", rxml_reader_expand, 0);
844
-
845
- #if LIBXML_VERSION >= 20618
846
- rb_define_method(cXMLReader, "byte_consumed", rxml_reader_byte_consumed, 0);
847
- #endif
848
- #if LIBXML_VERSION >= 20617
849
- rb_define_method(cXMLReader, "column_number", rxml_reader_column_number, 0);
850
- rb_define_method(cXMLReader, "line_number", rxml_reader_line_number, 0);
851
- #endif
852
- rb_define_method(cXMLReader, "default?", rxml_reader_default, 0);
853
- rb_define_method(cXMLReader, "empty_element?", rxml_reader_empty_element, 0);
854
- rb_define_method(cXMLReader, "namespace_declaration?", rxml_reader_namespace_declaration, 0);
855
- rb_define_method(cXMLReader, "valid?", rxml_reader_valid, 0);
856
-
857
- rb_define_const(cXMLReader, "LOADDTD", INT2FIX(XML_PARSER_LOADDTD));
858
- rb_define_const(cXMLReader, "DEFAULTATTRS", INT2FIX(XML_PARSER_DEFAULTATTRS));
859
- rb_define_const(cXMLReader, "VALIDATE", INT2FIX(XML_PARSER_VALIDATE));
860
- rb_define_const(cXMLReader, "SUBST_ENTITIES", INT2FIX(XML_PARSER_SUBST_ENTITIES));
861
-
862
- rb_define_const(cXMLReader, "SEVERITY_VALIDITY_WARNING", INT2FIX(XML_PARSER_SEVERITY_VALIDITY_WARNING));
863
- rb_define_const(cXMLReader, "SEVERITY_VALIDITY_ERROR", INT2FIX(XML_PARSER_SEVERITY_VALIDITY_ERROR));
864
- rb_define_const(cXMLReader, "SEVERITY_WARNING", INT2FIX(XML_PARSER_SEVERITY_WARNING));
865
- rb_define_const(cXMLReader, "SEVERITY_ERROR", INT2FIX(XML_PARSER_SEVERITY_ERROR));
866
-
867
- rb_define_const(cXMLReader, "TYPE_NONE", INT2FIX(XML_READER_TYPE_NONE));
868
- rb_define_const(cXMLReader, "TYPE_ELEMENT", INT2FIX(XML_READER_TYPE_ELEMENT));
869
- rb_define_const(cXMLReader, "TYPE_ATTRIBUTE", INT2FIX(XML_READER_TYPE_ATTRIBUTE));
870
- rb_define_const(cXMLReader, "TYPE_TEXT", INT2FIX(XML_READER_TYPE_TEXT));
871
- rb_define_const(cXMLReader, "TYPE_CDATA", INT2FIX(XML_READER_TYPE_CDATA));
872
- rb_define_const(cXMLReader, "TYPE_ENTITY_REFERENCE", INT2FIX(XML_READER_TYPE_ENTITY_REFERENCE));
873
- rb_define_const(cXMLReader, "TYPE_ENTITY", INT2FIX(XML_READER_TYPE_ENTITY));
874
- rb_define_const(cXMLReader, "TYPE_PROCESSING_INSTRUCTION", INT2FIX(XML_READER_TYPE_PROCESSING_INSTRUCTION));
875
- rb_define_const(cXMLReader, "TYPE_COMMENT", INT2FIX(XML_READER_TYPE_COMMENT));
876
- rb_define_const(cXMLReader, "TYPE_DOCUMENT", INT2FIX(XML_READER_TYPE_DOCUMENT));
877
- rb_define_const(cXMLReader, "TYPE_DOCUMENT_TYPE", INT2FIX(XML_READER_TYPE_DOCUMENT_TYPE));
878
- rb_define_const(cXMLReader, "TYPE_DOCUMENT_FRAGMENT", INT2FIX(XML_READER_TYPE_DOCUMENT_FRAGMENT));
879
- rb_define_const(cXMLReader, "TYPE_NOTATION", INT2FIX(XML_READER_TYPE_NOTATION));
880
- rb_define_const(cXMLReader, "TYPE_WHITESPACE", INT2FIX(XML_READER_TYPE_WHITESPACE));
881
- rb_define_const(cXMLReader, "TYPE_SIGNIFICANT_WHITESPACE", INT2FIX(XML_READER_TYPE_SIGNIFICANT_WHITESPACE));
882
- rb_define_const(cXMLReader, "TYPE_END_ELEMENT", INT2FIX(XML_READER_TYPE_END_ELEMENT));
883
- rb_define_const(cXMLReader, "TYPE_END_ENTITY", INT2FIX(XML_READER_TYPE_END_ENTITY));
884
- rb_define_const(cXMLReader, "TYPE_XML_DECLARATION", INT2FIX(XML_READER_TYPE_XML_DECLARATION));
885
-
886
- /* Read states */
887
- rb_define_const(cXMLReader, "MODE_INITIAL", INT2FIX(XML_TEXTREADER_MODE_INITIAL));
888
- rb_define_const(cXMLReader, "MODE_INTERACTIVE", INT2FIX(XML_TEXTREADER_MODE_INTERACTIVE));
889
- rb_define_const(cXMLReader, "MODE_ERROR", INT2FIX(XML_TEXTREADER_MODE_ERROR));
890
- rb_define_const(cXMLReader, "MODE_EOF", INT2FIX(XML_TEXTREADER_MODE_EOF));
891
- rb_define_const(cXMLReader, "MODE_CLOSED", INT2FIX(XML_TEXTREADER_MODE_CLOSED));
892
- rb_define_const(cXMLReader, "MODE_READING", INT2FIX(XML_TEXTREADER_MODE_READING));
893
- }
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
+
44
+ static VALUE
45
+ rxml_reader_new(VALUE class, xmlTextReaderPtr reader)
46
+ {
47
+ return Data_Wrap_Struct(class, NULL, xmlFreeTextReader, reader);
48
+ }
49
+
50
+ static xmlTextReaderPtr
51
+ rxml_text_reader_get(VALUE obj)
52
+ {
53
+ xmlTextReaderPtr xreader;
54
+ Data_Get_Struct(obj, xmlTextReader, xreader);
55
+ return xreader;
56
+ }
57
+
58
+ /*
59
+ * call-seq:
60
+ * XML::Reader.file(path, encoding=nil, options=0) -> reader
61
+ *
62
+ * Parse an XML file from the filesystem or the network. The parsing flags
63
+ * options are a combination of xmlParserOption.
64
+ */
65
+ static VALUE
66
+ rxml_reader_new_file(int argc, VALUE *argv, VALUE self)
67
+ {
68
+ xmlTextReaderPtr xreader;
69
+ VALUE rpath, rencoding, roptions;
70
+ char *xpath;
71
+ char *xencoding;
72
+ int options;
73
+
74
+ rb_scan_args(argc, argv, "12", &rpath, &rencoding, &roptions);
75
+
76
+ xpath = NIL_P(rpath) ? NULL : StringValueCStr(rpath);
77
+ xencoding = NIL_P(rencoding) ? NULL : StringValueCStr(rencoding);
78
+ options = NIL_P(roptions) ? 0 : FIX2INT(roptions);
79
+
80
+ xreader = xmlReaderForFile(xpath, xencoding, options);
81
+
82
+ if (xreader == NULL)
83
+ rxml_raise(&xmlLastError);
84
+
85
+ return rxml_reader_new(self, xreader);
86
+ }
87
+
88
+ /*
89
+ * call-seq:
90
+ * XML::Reader.io(io, url=nil, encoding=nil, options=0) -> reader
91
+ *
92
+ * Parse an XML file from a file handle. The parsing flags options are
93
+ * a combination of xmlParserOption.
94
+ */
95
+ static VALUE
96
+ rxml_reader_new_io(int argc, VALUE *argv, VALUE self)
97
+ {
98
+ xmlTextReaderPtr xreader;
99
+ VALUE rio, rurl, rencoding, roptions;
100
+ char *xurl;
101
+ char *xencoding;
102
+ int options;
103
+
104
+ rb_scan_args(argc, argv, "13", &rio, &rurl, &rencoding, &roptions);
105
+
106
+ xurl = NIL_P(rurl) ? NULL : StringValueCStr(rurl);
107
+ xencoding = NIL_P(rencoding) ? NULL : StringValueCStr(rencoding);
108
+ options = NIL_P(roptions) ? 0 : FIX2INT(roptions);
109
+
110
+ xreader = xmlReaderForIO((xmlInputReadCallback) rxml_read_callback, NULL,
111
+ (void *)rio,
112
+ xurl, xencoding, options);
113
+
114
+ if (xreader == NULL)
115
+ rxml_raise(&xmlLastError);
116
+
117
+ return rxml_reader_new(self, xreader);
118
+ }
119
+
120
+ /*
121
+ * call-seq:
122
+ * XML::Reader.walker(doc) -> reader
123
+ * XML::Reader.document(doc) -> reader
124
+ *
125
+ * Create an XML text reader for a preparsed document.
126
+ */
127
+ VALUE
128
+ rxml_reader_new_walker(VALUE self, VALUE doc)
129
+ {
130
+ xmlDocPtr xdoc;
131
+ xmlTextReaderPtr xreader;
132
+
133
+ Data_Get_Struct(doc, xmlDoc, xdoc);
134
+
135
+ xreader = xmlReaderWalker(xdoc);
136
+
137
+ if (xreader == NULL)
138
+ rxml_raise(&xmlLastError);
139
+
140
+ return rxml_reader_new(self, xreader);
141
+ }
142
+
143
+ /*
144
+ * call-seq:
145
+ * XML::Reader.new(data, url=nil, encoding=nil, options=0) -> reader
146
+ * XML::Reader.string(data, url=nil, encoding=nil, options=0) -> reader
147
+ *
148
+ * Create an XML text reader for an XML in-memory document. The parsing flags
149
+ * options are a combination of xmlParserOption.
150
+ */
151
+ static VALUE
152
+ rxml_reader_new_data(int argc, VALUE *argv, VALUE self)
153
+ {
154
+ xmlTextReaderPtr xreader;
155
+ VALUE rdata, rurl, rencoding, roptions;
156
+ char *xdata;
157
+ char *xurl;
158
+ char *xencoding;
159
+ int options;
160
+
161
+ rb_scan_args(argc, argv, "13", &rdata, &rurl, &rencoding, &roptions);
162
+
163
+ xdata = NIL_P(rdata) ? NULL : StringValueCStr(rdata);
164
+ xurl = NIL_P(rurl) ? NULL : StringValueCStr(rurl);
165
+ xencoding = NIL_P(rencoding) ? NULL : StringValueCStr(rencoding);
166
+ options = NIL_P(roptions) ? 0 : FIX2INT(roptions);
167
+
168
+ xreader = xmlReaderForMemory(xdata, strlen(xdata),
169
+ xurl, xencoding, options);
170
+
171
+ if (xreader == NULL)
172
+ rxml_raise(&xmlLastError);
173
+
174
+ return rxml_reader_new(self, xreader);
175
+ }
176
+
177
+ /*
178
+ * call-seq:
179
+ * parser.close -> code
180
+ *
181
+ * This method releases any resources allocated by the current instance
182
+ * changes the state to Closed and close any underlying input.
183
+ */
184
+ static VALUE
185
+ rxml_reader_close(VALUE self)
186
+ {
187
+ return INT2FIX(xmlTextReaderClose(rxml_text_reader_get(self)));
188
+ }
189
+
190
+ /*
191
+ * call-seq:
192
+ * parser.move_to_attribute(val) -> code
193
+ *
194
+ * Move the position of the current instance to the attribute with the
195
+ * specified index (if +val+ is an integer) or name (if +val+ is a string)
196
+ * relative to the containing element.
197
+ */
198
+ static VALUE
199
+ rxml_reader_move_to_attr(VALUE self, VALUE val)
200
+ {
201
+ xmlTextReaderPtr xreader;
202
+ int ret;
203
+
204
+ xreader = rxml_text_reader_get(self);
205
+
206
+ if (TYPE(val) == T_FIXNUM) {
207
+ ret = xmlTextReaderMoveToAttributeNo(xreader, FIX2INT(val));
208
+ }
209
+ else {
210
+ ret = xmlTextReaderMoveToAttribute(xreader, (const xmlChar *)StringValueCStr(val));
211
+ }
212
+
213
+ return INT2FIX(ret);
214
+ }
215
+
216
+ /*
217
+ * call-seq:
218
+ * reader.move_to_first_attribute -> code
219
+ *
220
+ * Move the position of the current instance to the first attribute associated
221
+ * with the current node.
222
+ */
223
+ static VALUE
224
+ rxml_reader_move_to_first_attr(VALUE self)
225
+ {
226
+ return INT2FIX(xmlTextReaderMoveToFirstAttribute(rxml_text_reader_get(self)));
227
+ }
228
+
229
+ /*
230
+ * call-seq:
231
+ * reader.move_to_next_attribute -> code
232
+ *
233
+ * Move the position of the current instance to the next attribute associated
234
+ * with the current node.
235
+ */
236
+ static VALUE
237
+ rxml_reader_move_to_next_attr(VALUE self)
238
+ {
239
+ return INT2FIX(xmlTextReaderMoveToNextAttribute(rxml_text_reader_get(self)));
240
+ }
241
+
242
+ /*
243
+ * call-seq:
244
+ * reader.move_to_element -> code
245
+ *
246
+ * Move the position of the current instance to the node that contains the
247
+ * current attribute node.
248
+ */
249
+ static VALUE
250
+ rxml_reader_move_to_element(VALUE self)
251
+ {
252
+ return INT2FIX(xmlTextReaderMoveToElement(rxml_text_reader_get(self)));
253
+ }
254
+
255
+ /*
256
+ * call-seq:
257
+ * reader.next -> code
258
+ *
259
+ * Skip to the node following the current one in document order while avoiding
260
+ * the subtree if any.
261
+ */
262
+ static VALUE
263
+ rxml_reader_next(VALUE self)
264
+ {
265
+ return INT2FIX(xmlTextReaderNext(rxml_text_reader_get(self)));
266
+ }
267
+
268
+ /*
269
+ * call-seq:
270
+ * reader.next_sibling -> code
271
+ *
272
+ * Skip to the node following the current one in document order while avoiding
273
+ * the subtree if any. Currently implemented only for Readers built on a
274
+ * document.
275
+ */
276
+ static VALUE
277
+ rxml_reader_next_sibling(VALUE self)
278
+ {
279
+ return INT2FIX(xmlTextReaderNextSibling(rxml_text_reader_get(self)));
280
+ }
281
+
282
+ /*
283
+ * call-seq:
284
+ * reader.node_type -> type
285
+ *
286
+ * Get the node type of the current node. Reference:
287
+ * http://dotgnu.org/pnetlib-doc/System/Xml/XmlNodeType.html
288
+ */
289
+ static VALUE
290
+ rxml_reader_node_type(VALUE self)
291
+ {
292
+ return INT2FIX(xmlTextReaderNodeType(rxml_text_reader_get(self)));
293
+ }
294
+
295
+ /*
296
+ * call-seq:
297
+ * reader.normalization -> value
298
+ *
299
+ * The value indicating whether to normalize white space and attribute values.
300
+ * Since attribute value and end of line normalizations are a MUST in the XML
301
+ * specification only the value true is accepted. The broken bahaviour of
302
+ * accepting out of range character entities like &#0; is of course not
303
+ * supported either.
304
+ *
305
+ * Return 1 or -1 in case of error.
306
+ */
307
+ static VALUE
308
+ rxml_reader_normalization(VALUE self)
309
+ {
310
+ return INT2FIX(xmlTextReaderNormalization(rxml_text_reader_get(self)));
311
+ }
312
+
313
+ /*
314
+ * call-seq:
315
+ * reader.read -> code
316
+ *
317
+ * Move the position of the current instance to the next node in the stream,
318
+ * exposing its properties.
319
+ *
320
+ * Return 1 if the node was read successfully, 0 if there is no more nodes to
321
+ * read, or -1 in case of error.
322
+ */
323
+ static VALUE
324
+ rxml_reader_read(VALUE self)
325
+ {
326
+ return INT2FIX(xmlTextReaderRead(rxml_text_reader_get(self)));
327
+ }
328
+
329
+ /*
330
+ * call-seq:
331
+ * reader.read_attribute_value -> code
332
+ *
333
+ * Parse an attribute value into one or more Text and EntityReference nodes.
334
+ *
335
+ * Return 1 in case of success, 0 if the reader was not positionned on an
336
+ * attribute node or all the attribute values have been read, or -1 in case of
337
+ * error.
338
+ */
339
+ static VALUE
340
+ rxml_reader_read_attr_value(VALUE self)
341
+ {
342
+ return INT2FIX(xmlTextReaderReadAttributeValue(rxml_text_reader_get(self)));
343
+ }
344
+
345
+ /*
346
+ * call-seq:
347
+ * reader.read_inner_xml -> data
348
+ *
349
+ * Read the contents of the current node, including child nodes and markup.
350
+ *
351
+ * Return a string containing the XML content, or nil if the current node is
352
+ * neither an element nor attribute, or has no child nodes.
353
+ */
354
+ static VALUE
355
+ rxml_reader_read_inner_xml(VALUE self)
356
+ {
357
+ const xmlChar *result = xmlTextReaderReadInnerXml(rxml_text_reader_get(self));
358
+ return (result == NULL ? Qnil : rb_str_new2(result));
359
+ }
360
+
361
+ /*
362
+ * call-seq:
363
+ * reader.read_outer_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
+ rxml_reader_read_outer_xml(VALUE self)
372
+ {
373
+ const xmlChar *result = xmlTextReaderReadOuterXml(rxml_text_reader_get(self));
374
+ return (result == NULL ? Qnil : rb_str_new2(result));
375
+ }
376
+
377
+ /*
378
+ * call-seq:
379
+ * reader.read_state -> state
380
+ *
381
+ * Get the read state of the reader.
382
+ */
383
+ static VALUE
384
+ rxml_reader_read_state(VALUE self)
385
+ {
386
+ return INT2FIX(xmlTextReaderReadState(rxml_text_reader_get(self)));
387
+ }
388
+
389
+ /*
390
+ * call-seq:
391
+ * reader.read_string -> string
392
+ *
393
+ * Read the contents of an element or a text node as a string.
394
+ *
395
+ * Return a string containing the contents of the Element or Text node, or nil
396
+ * if the reader is positioned on any other type of node.
397
+ */
398
+ static VALUE
399
+ rxml_reader_read_string(VALUE self)
400
+ {
401
+ const xmlChar *result = xmlTextReaderReadString(rxml_text_reader_get(self));
402
+ return (result == NULL ? Qnil : rb_str_new2(result));
403
+ }
404
+
405
+ /*
406
+ * call-seq:
407
+ * reader.relax_ng_validate(rng) -> code
408
+ *
409
+ * Use RelaxNG to validate the document as it is processed. Activation is only
410
+ * possible before the first read. If +rng+ is nil, the RelaxNG validation is
411
+ * desactivated.
412
+ *
413
+ * Return 0 in case the RelaxNG validation could be (des)activated and -1 in
414
+ * case of error.
415
+ */
416
+ static VALUE
417
+ rxml_reader_relax_ng_validate(VALUE self, VALUE rng)
418
+ {
419
+ char *xrng = NIL_P(rng) ? NULL : StringValueCStr(rng);
420
+ return INT2FIX(xmlTextReaderRelaxNGValidate(rxml_text_reader_get(self), xrng));
421
+ }
422
+
423
+ #if LIBXML_VERSION >= 20620
424
+ /*
425
+ * call-seq:
426
+ * reader.schema_validate(schema) -> code
427
+ *
428
+ * Use W3C XSD schema to validate the document as it is processed. Activation
429
+ * is only possible before the first read. If +schema+ is nil, then XML Schema
430
+ * validation is desactivated.
431
+ *
432
+ * Return 0 in case the schemas validation could be (de)activated and -1 in
433
+ * case of error.
434
+ */
435
+ static VALUE
436
+ rxml_reader_schema_validate(VALUE self, VALUE xsd)
437
+ {
438
+ char *xxsd = NIL_P(xsd) ? NULL : StringValueCStr(xsd);
439
+ int status = xmlTextReaderSchemaValidate(rxml_text_reader_get(self), xxsd);
440
+ return INT2FIX(status);
441
+ }
442
+ #endif
443
+
444
+ /*
445
+ * call-seq:
446
+ * reader.name -> name
447
+ *
448
+ * Return the qualified name of the node.
449
+ */
450
+ static VALUE
451
+ rxml_reader_name(VALUE self)
452
+ {
453
+ const xmlChar *result = xmlTextReaderConstName(rxml_text_reader_get(self));
454
+ return (result == NULL ? Qnil : rb_str_new2(result));
455
+ }
456
+
457
+ /*
458
+ * call-seq:
459
+ * reader.local_name -> name
460
+ *
461
+ * Return the local name of the node.
462
+ */
463
+ static VALUE
464
+ rxml_reader_local_name(VALUE self)
465
+ {
466
+ const xmlChar *result = xmlTextReaderConstLocalName(rxml_text_reader_get(self));
467
+ return (result == NULL ? Qnil : rb_str_new2(result));
468
+ }
469
+
470
+ /*
471
+ * call-seq:
472
+ * reader.attribute_count -> count
473
+ *
474
+ * Provide the number of attributes of the current node.
475
+ */
476
+ static VALUE
477
+ rxml_reader_attr_count(VALUE self)
478
+ {
479
+ return INT2FIX(xmlTextReaderAttributeCount(rxml_text_reader_get(self)));
480
+ }
481
+
482
+ /*
483
+ * call-seq:
484
+ * reader.encoding -> encoding
485
+ *
486
+ * Determine the encoding of the document being read.
487
+ */
488
+ static VALUE
489
+ rxml_reader_encoding(VALUE self)
490
+ {
491
+ const xmlChar *result = xmlTextReaderConstEncoding(rxml_text_reader_get(self));
492
+ return (result == NULL ? Qnil : rb_str_new2(result));
493
+ }
494
+
495
+ /*
496
+ * call-seq:
497
+ * reader.base_uri -> URI
498
+ *
499
+ * Determine the base URI of the node.
500
+ */
501
+ static VALUE
502
+ rxml_reader_base_uri(VALUE self)
503
+ {
504
+ const xmlChar *result = xmlTextReaderConstBaseUri(rxml_text_reader_get(self));
505
+ return (result == NULL ? Qnil : rb_str_new2(result));
506
+ }
507
+
508
+ /*
509
+ * call-seq:
510
+ * reader.namespace_uri -> URI
511
+ *
512
+ * Determine the namespace URI of the node.
513
+ */
514
+ static VALUE
515
+ rxml_reader_namespace_uri(VALUE self)
516
+ {
517
+ const xmlChar *result = xmlTextReaderConstNamespaceUri(rxml_text_reader_get(self));
518
+ return (result == NULL ? Qnil : rb_str_new2(result));
519
+ }
520
+
521
+ /*
522
+ * call-seq:
523
+ * reader.value -> text
524
+ *
525
+ * Provide the text value of the node if present.
526
+ */
527
+ static VALUE
528
+ rxml_reader_value(VALUE self)
529
+ {
530
+ const xmlChar *result = xmlTextReaderConstValue(rxml_text_reader_get(self));
531
+ return (result == NULL ? Qnil : rb_str_new2(result));
532
+ }
533
+
534
+ /*
535
+ * call-seq:
536
+ * reader.prefix -> prefix
537
+ *
538
+ * Get a shorthand reference to the namespace associated with the node.
539
+ */
540
+ static VALUE
541
+ rxml_reader_prefix(VALUE self)
542
+ {
543
+ const xmlChar *result = xmlTextReaderConstPrefix(rxml_text_reader_get(self));
544
+ return (result == NULL ? Qnil : rb_str_new2(result));
545
+ }
546
+
547
+ /*
548
+ * call-seq:
549
+ * reader.depth -> depth
550
+ *
551
+ * Get the depth of the node in the tree.
552
+ */
553
+ static VALUE
554
+ rxml_reader_depth(VALUE self)
555
+ {
556
+ return INT2FIX(xmlTextReaderDepth(rxml_text_reader_get(self)));
557
+ }
558
+
559
+ /*
560
+ * call-seq:
561
+ * reader.quote_char -> char
562
+ *
563
+ * Get the quotation mark character used to enclose the value of an attribute,
564
+ * as an integer value (and -1 in case of error).
565
+ */
566
+ static VALUE
567
+ rxml_reader_quote_char(VALUE self)
568
+ {
569
+ return INT2FIX(xmlTextReaderQuoteChar(rxml_text_reader_get(self)));
570
+ }
571
+
572
+ /*
573
+ * call-seq:
574
+ * reader.standalone -> code
575
+ *
576
+ * Determine the standalone status of the document being read.
577
+ *
578
+ * Return 1 if the document was declared to be standalone, 0 if it was
579
+ * declared to be not standalone, or -1 if the document did not specify its
580
+ * standalone status or in case of error.
581
+ */
582
+ static VALUE
583
+ rxml_reader_standalone(VALUE self)
584
+ {
585
+ return INT2FIX(xmlTextReaderStandalone(rxml_text_reader_get(self)));
586
+ }
587
+
588
+ /*
589
+ * call-seq:
590
+ * reader.xml_lang -> value
591
+ *
592
+ * Get the xml:lang scope within which the node resides.
593
+ */
594
+ static VALUE
595
+ rxml_reader_xml_lang(VALUE self)
596
+ {
597
+ const xmlChar *result = xmlTextReaderConstXmlLang(rxml_text_reader_get(self));
598
+ return (result == NULL ? Qnil : rb_str_new2(result));
599
+ }
600
+
601
+ /*
602
+ * call-seq:
603
+ * reader.xml_version -> version
604
+ *
605
+ * Determine the XML version of the document being read.
606
+ */
607
+ static VALUE
608
+ rxml_reader_xml_version(VALUE self)
609
+ {
610
+ const xmlChar *result = xmlTextReaderConstXmlVersion(rxml_text_reader_get(self));
611
+ return (result == NULL ? Qnil : rb_str_new2(result));
612
+ }
613
+
614
+ /*
615
+ * call-seq:
616
+ * reader.has_attributes? -> bool
617
+ *
618
+ * Get whether the node has attributes.
619
+ */
620
+ static VALUE
621
+ rxml_reader_has_attributes(VALUE self)
622
+ {
623
+ return xmlTextReaderHasAttributes(rxml_text_reader_get(self)) ? Qtrue : Qfalse;
624
+ }
625
+
626
+ /*
627
+ * call-seq:
628
+ * reader.has_value? -> bool
629
+ *
630
+ * Get whether the node can have a text value.
631
+ */
632
+ static VALUE
633
+ rxml_reader_has_value(VALUE self)
634
+ {
635
+ return xmlTextReaderHasValue(rxml_text_reader_get(self)) ? Qtrue : Qfalse;
636
+ }
637
+
638
+ /*
639
+ * call-seq:
640
+ * reader[key] -> value
641
+ *
642
+ * Provide the value of the attribute with the specified index (if +key+ is an
643
+ * integer) or with the specified name (if +key+ is a string) relative to the
644
+ * containing element, as a string.
645
+ */
646
+ static VALUE
647
+ rxml_reader_attribute(VALUE self, VALUE key)
648
+ {
649
+ xmlTextReaderPtr reader;
650
+ xmlChar *attr;
651
+
652
+ reader = rxml_text_reader_get(self);
653
+
654
+ if (TYPE(key) == T_FIXNUM) {
655
+ attr = xmlTextReaderGetAttributeNo(reader, FIX2INT(key));
656
+ }
657
+ else {
658
+ attr = xmlTextReaderGetAttribute(reader, (const xmlChar *)StringValueCStr(key));
659
+ }
660
+ return (attr == NULL ? Qnil : rb_str_new2(attr));
661
+ }
662
+
663
+ /*
664
+ * call-seq:
665
+ * reader.lookup_namespace(prefix) -> value
666
+ *
667
+ * Resolve a namespace prefix in the scope of the current element.
668
+ * To return the default namespace, specify nil as +prefix+.
669
+ */
670
+ static VALUE
671
+ rxml_reader_lookup_namespace(VALUE self, VALUE prefix)
672
+ {
673
+ const xmlChar *result = xmlTextReaderLookupNamespace(rxml_text_reader_get(self), (const xmlChar *)StringValueCStr(prefix));
674
+ return (result == NULL ? Qnil : rb_str_new2(result));
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
+ rxml_reader_expand(VALUE self)
688
+ {
689
+ xmlNodePtr node;
690
+ xmlDocPtr doc;
691
+ xmlTextReaderPtr reader = rxml_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
+ rxml_document_wrap(doc);
706
+
707
+ return rxml_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
+ rxml_reader_byte_consumed(VALUE self)
720
+ {
721
+ return INT2NUM(xmlTextReaderByteConsumed(rxml_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
+ rxml_reader_column_number(VALUE self)
734
+ {
735
+ return INT2NUM(xmlTextReaderGetParserColumnNumber(rxml_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
+ rxml_reader_line_number(VALUE self)
746
+ {
747
+ return INT2NUM(xmlTextReaderGetParserLineNumber(rxml_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
+ rxml_reader_default(VALUE self)
760
+ {
761
+ return xmlTextReaderIsDefault(rxml_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
+ rxml_reader_namespace_declaration(VALUE self)
773
+ {
774
+ return xmlTextReaderIsNamespaceDecl(rxml_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
+ rxml_reader_empty_element(VALUE self)
785
+ {
786
+ return xmlTextReaderIsEmptyElement(rxml_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
+ rxml_reader_valid(VALUE self)
797
+ {
798
+ return xmlTextReaderIsValid(rxml_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", rxml_reader_new_file, -1);
813
+ rb_define_singleton_method(cXMLReader, "io", rxml_reader_new_io, -1);
814
+ rb_define_singleton_method(cXMLReader, "walker", rxml_reader_new_walker, 1);
815
+ rb_define_alias(CLASS_OF(cXMLReader), "document", "walker");
816
+ rb_define_singleton_method(cXMLReader, "new", rxml_reader_new_data, -1);
817
+ rb_define_alias(CLASS_OF(cXMLReader), "string", "new");
818
+
819
+ rb_define_method(cXMLReader, "close", rxml_reader_close, 0);
820
+
821
+ rb_define_method(cXMLReader, "move_to_attribute", rxml_reader_move_to_attr, 1);
822
+ rb_define_method(cXMLReader, "move_to_first_attribute", rxml_reader_move_to_first_attr, 0);
823
+ rb_define_method(cXMLReader, "move_to_next_attribute", rxml_reader_move_to_next_attr, 0);
824
+ rb_define_method(cXMLReader, "move_to_element", rxml_reader_move_to_element, 0);
825
+ rb_define_method(cXMLReader, "next", rxml_reader_next, 0);
826
+ rb_define_method(cXMLReader, "next_sibling", rxml_reader_next_sibling, 0);
827
+ rb_define_method(cXMLReader, "read", rxml_reader_read, 0);
828
+ rb_define_method(cXMLReader, "read_attribute_value", rxml_reader_read_attr_value, 0);
829
+ rb_define_method(cXMLReader, "read_inner_xml", rxml_reader_read_inner_xml, 0);
830
+ rb_define_method(cXMLReader, "read_outer_xml", rxml_reader_read_outer_xml, 0);
831
+ rb_define_method(cXMLReader, "read_state", rxml_reader_read_state, 0);
832
+ rb_define_method(cXMLReader, "read_string", rxml_reader_read_string, 0);
833
+
834
+ rb_define_method(cXMLReader, "relax_ng_validate", rxml_reader_relax_ng_validate, 1);
835
+ #if LIBXML_VERSION >= 20620
836
+ rb_define_method(cXMLReader, "schema_validate", rxml_reader_schema_validate, 1);
837
+ #endif
838
+
839
+ rb_define_method(cXMLReader, "node_type", rxml_reader_node_type, 0);
840
+ rb_define_method(cXMLReader, "normalization", rxml_reader_normalization, 0);
841
+ rb_define_method(cXMLReader, "attribute_count", rxml_reader_attr_count, 0);
842
+ rb_define_method(cXMLReader, "name", rxml_reader_name, 0);
843
+ rb_define_method(cXMLReader, "local_name", rxml_reader_local_name, 0);
844
+ rb_define_method(cXMLReader, "encoding", rxml_reader_encoding, 0);
845
+ rb_define_method(cXMLReader, "base_uri", rxml_reader_base_uri, 0);
846
+ rb_define_method(cXMLReader, "namespace_uri", rxml_reader_namespace_uri, 0);
847
+ rb_define_method(cXMLReader, "xml_lang", rxml_reader_xml_lang, 0);
848
+ rb_define_method(cXMLReader, "xml_version", rxml_reader_xml_version, 0);
849
+ rb_define_method(cXMLReader, "prefix", rxml_reader_prefix, 0);
850
+ rb_define_method(cXMLReader, "depth", rxml_reader_depth, 0);
851
+ rb_define_method(cXMLReader, "quote_char", rxml_reader_quote_char, 0);
852
+ rb_define_method(cXMLReader, "standalone", rxml_reader_standalone, 0);
853
+
854
+ rb_define_method(cXMLReader, "has_attributes?", rxml_reader_has_attributes, 0);
855
+ rb_define_method(cXMLReader, "[]", rxml_reader_attribute, 1);
856
+ rb_define_method(cXMLReader, "has_value?", rxml_reader_has_value, 0);
857
+ rb_define_method(cXMLReader, "value", rxml_reader_value, 0);
858
+
859
+ rb_define_method(cXMLReader, "lookup_namespace", rxml_reader_lookup_namespace, 1);
860
+ rb_define_method(cXMLReader, "expand", rxml_reader_expand, 0);
861
+
862
+ #if LIBXML_VERSION >= 20618
863
+ rb_define_method(cXMLReader, "byte_consumed", rxml_reader_byte_consumed, 0);
864
+ #endif
865
+ #if LIBXML_VERSION >= 20617
866
+ rb_define_method(cXMLReader, "column_number", rxml_reader_column_number, 0);
867
+ rb_define_method(cXMLReader, "line_number", rxml_reader_line_number, 0);
868
+ #endif
869
+ rb_define_method(cXMLReader, "default?", rxml_reader_default, 0);
870
+ rb_define_method(cXMLReader, "empty_element?", rxml_reader_empty_element, 0);
871
+ rb_define_method(cXMLReader, "namespace_declaration?", rxml_reader_namespace_declaration, 0);
872
+ rb_define_method(cXMLReader, "valid?", rxml_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
+ }