libxml-ruby 0.9.3 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ }