libxml-ruby 0.3.8.4 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/CHANGELOG +6 -0
  2. data/LICENSE +1 -1
  3. data/README +1 -1
  4. data/Rakefile +8 -5
  5. data/TODO +1 -1
  6. data/ext/xml/extconf.rb +4 -5
  7. data/ext/xml/libxml.c +5 -2
  8. data/ext/xml/libxml.h +16 -7
  9. data/ext/xml/libxml.rb +3 -3
  10. data/ext/xml/ruby_xml_attr.c +118 -99
  11. data/ext/xml/ruby_xml_attr.h +4 -7
  12. data/ext/xml/ruby_xml_document.c +131 -170
  13. data/ext/xml/ruby_xml_document.h +5 -9
  14. data/ext/xml/ruby_xml_html_parser.c +453 -0
  15. data/ext/xml/ruby_xml_html_parser.h +29 -0
  16. data/ext/xml/ruby_xml_node.c +219 -253
  17. data/ext/xml/ruby_xml_node.h +4 -7
  18. data/ext/xml/ruby_xml_node_set.c +6 -6
  19. data/ext/xml/ruby_xml_node_set.h +1 -1
  20. data/ext/xml/ruby_xml_ns.c +1 -1
  21. data/ext/xml/ruby_xml_ns.h +1 -1
  22. data/ext/xml/ruby_xml_parser.c +5 -8
  23. data/ext/xml/ruby_xml_parser.h +1 -1
  24. data/ext/xml/ruby_xml_parser_context.c +3 -4
  25. data/ext/xml/ruby_xml_parser_context.h +1 -1
  26. data/ext/xml/ruby_xml_reader.c +893 -0
  27. data/ext/xml/ruby_xml_reader.h +14 -0
  28. data/ext/xml/ruby_xml_sax_parser.c +255 -204
  29. data/ext/xml/ruby_xml_sax_parser.h +6 -2
  30. data/ext/xml/ruby_xml_tree.c +1 -1
  31. data/ext/xml/ruby_xml_tree.h +1 -1
  32. data/ext/xml/ruby_xml_xinclude.c +1 -1
  33. data/ext/xml/ruby_xml_xinclude.h +1 -1
  34. data/ext/xml/ruby_xml_xpath.c +3 -2
  35. data/ext/xml/ruby_xml_xpath.h +1 -1
  36. data/ext/xml/ruby_xml_xpath_context.c +4 -4
  37. data/ext/xml/ruby_xml_xpath_context.h +1 -1
  38. data/ext/xml/ruby_xml_xpointer.c +10 -4
  39. data/ext/xml/ruby_xml_xpointer.h +1 -1
  40. data/ext/xml/ruby_xml_xpointer_context.c +1 -1
  41. data/ext/xml/ruby_xml_xpointer_context.h +1 -1
  42. data/ext/xml/sax_parser_callbacks.inc +55 -54
  43. data/tests/model/rubynet_project +1 -1
  44. data/tests/model/simple.xml +7 -0
  45. data/tests/tc_xml_document.rb +1 -1
  46. data/tests/tc_xml_document_write.rb +1 -1
  47. data/tests/tc_xml_document_write2.rb +1 -1
  48. data/tests/tc_xml_document_write3.rb +1 -1
  49. data/tests/tc_xml_html_parser.rb +60 -0
  50. data/tests/tc_xml_node.rb +1 -1
  51. data/tests/tc_xml_node2.rb +1 -1
  52. data/tests/tc_xml_node3.rb +1 -1
  53. data/tests/tc_xml_node4.rb +8 -5
  54. data/tests/tc_xml_node5.rb +1 -1
  55. data/tests/tc_xml_node6.rb +1 -1
  56. data/tests/tc_xml_node7.rb +1 -1
  57. data/tests/tc_xml_node_set.rb +1 -1
  58. data/tests/tc_xml_node_set2.rb +1 -1
  59. data/tests/tc_xml_node_xlink.rb +1 -1
  60. data/tests/tc_xml_parser.rb +5 -1
  61. data/tests/tc_xml_parser2.rb +1 -1
  62. data/tests/tc_xml_parser3.rb +1 -1
  63. data/tests/tc_xml_parser4.rb +1 -1
  64. data/tests/tc_xml_parser5.rb +1 -1
  65. data/tests/tc_xml_parser6.rb +1 -1
  66. data/tests/tc_xml_parser7.rb +1 -1
  67. data/tests/tc_xml_parser8.rb +1 -1
  68. data/tests/tc_xml_parser_context.rb +1 -1
  69. data/tests/tc_xml_reader.rb +101 -0
  70. data/tests/tc_xml_sax_parser.rb +95 -0
  71. data/tests/tc_xml_xinclude.rb +1 -1
  72. data/tests/tc_xml_xpath.rb +1 -1
  73. data/tests/tc_xml_xpointer.rb +1 -1
  74. metadata +79 -73
  75. data/ext/xml/ruby_xml_attribute.c +0 -224
  76. data/ext/xml/ruby_xml_attribute.h +0 -21
  77. data/tests/test_xml_sax_parser.rb +0 -64
@@ -0,0 +1,893 @@
1
+ /* Copyright (c) 2006-2007 Apple Inc.
2
+ * Please see the LICENSE file for copyright and distribution information. */
3
+
4
+ #include "libxml.h"
5
+ #include "ruby_xml_reader.h"
6
+
7
+ #define CSTR2RVAL(x) (x == NULL ? Qnil : rb_str_new2((const char *)x))
8
+ #define RVAL2CSTR(x) (StringValueCStr(x))
9
+
10
+ static inline VALUE
11
+ __rb_str_new_and_free(xmlChar *x)
12
+ {
13
+ if (x != NULL) {
14
+ VALUE v = rb_str_new2((const char *)x);
15
+ xmlFree(x);
16
+ return v;
17
+ }
18
+ return Qnil;
19
+ }
20
+
21
+ #define CSTR2RVAL2(x) (__rb_str_new_and_free(x))
22
+
23
+ VALUE cXMLReader;
24
+ static ID error_handler_block_ivar_id;
25
+
26
+ static VALUE
27
+ ruby_xml_reader_new(VALUE class, xmlTextReaderPtr reader)
28
+ {
29
+ return Data_Wrap_Struct(class, NULL, xmlFreeTextReader, reader);
30
+ }
31
+
32
+ static xmlTextReaderPtr
33
+ __ruby_xml_parser_get(VALUE obj)
34
+ {
35
+ xmlTextReaderPtr ptr;
36
+ Data_Get_Struct(obj, xmlTextReader, ptr);
37
+ return ptr;
38
+ }
39
+
40
+ #if defined(_SELF)
41
+ # undef _SELF
42
+ #endif
43
+ #define _SELF(x) (__ruby_xml_parser_get(x))
44
+
45
+ /*
46
+ * call-seq:
47
+ * XML::Reader.file(path, encoding=nil, options=0) -> reader
48
+ *
49
+ * Parse an XML file from the filesystem or the network. The parsing flags
50
+ * options are a combination of xmlParserOption.
51
+ */
52
+ static VALUE
53
+ ruby_xml_reader_new_file(int argc, VALUE *argv, VALUE self)
54
+ {
55
+ xmlTextReaderPtr reader;
56
+ VALUE path, encoding, options;
57
+
58
+ rb_scan_args(argc, argv, "12", &path, &encoding, &options);
59
+
60
+ reader = xmlReaderForFile(RVAL2CSTR(path),
61
+ NIL_P(encoding) ? NULL : RVAL2CSTR(encoding),
62
+ NIL_P(options) ? 0 : FIX2INT(options));
63
+ if (reader == NULL)
64
+ rb_raise(rb_eRuntimeError,
65
+ "cannot create text reader for given XML file at path '%s'",
66
+ RVAL2CSTR(path));
67
+
68
+ return ruby_xml_reader_new(self, reader);
69
+ }
70
+
71
+ /*
72
+ * call-seq:
73
+ * XML::Reader.walker(doc) -> reader
74
+ * XML::Reader.document(doc) -> reader
75
+ *
76
+ * Create an XML text reader for a preparsed document.
77
+ */
78
+ VALUE
79
+ ruby_xml_reader_new_walker(VALUE self, VALUE doc)
80
+ {
81
+ ruby_xml_document_t *rxd;
82
+ xmlTextReaderPtr reader;
83
+
84
+ Data_Get_Struct(doc, ruby_xml_document_t, rxd);
85
+
86
+ reader = xmlReaderWalker(rxd->doc);
87
+ if (reader == NULL)
88
+ rb_raise(rb_eRuntimeError, "cannot create text reader for given document");
89
+
90
+ return ruby_xml_reader_new(self, reader);
91
+ }
92
+
93
+ /*
94
+ * call-seq:
95
+ * XML::Reader.new(data, url=nil, encoding=nil, options=0) -> reader
96
+ * XML::Reader.string(data, url=nil, encoding=nil, options=0) -> reader
97
+ *
98
+ * Create an XML text reader for an XML in-memory document. The parsing flags
99
+ * options are a combination of xmlParserOption.
100
+ */
101
+ static VALUE
102
+ ruby_xml_reader_new_data(int argc, VALUE *argv, VALUE self)
103
+ {
104
+ xmlTextReaderPtr reader;
105
+ VALUE data, url, encoding, options;
106
+ char *c_data;
107
+
108
+ rb_scan_args(argc, argv, "13", &data, &url, &encoding, &options);
109
+
110
+ c_data = RVAL2CSTR(data);
111
+ reader = xmlReaderForMemory(c_data,
112
+ strlen(c_data),
113
+ NIL_P(url) ? NULL : RVAL2CSTR(url),
114
+ NIL_P(encoding) ? NULL : RVAL2CSTR(encoding),
115
+ NIL_P(options) ? 0 : FIX2INT(options));
116
+ if (reader == NULL)
117
+ rb_raise(rb_eRuntimeError, "cannot create text reader for given data");
118
+
119
+ return ruby_xml_reader_new(self, reader);
120
+ }
121
+
122
+ /*
123
+ * call-seq:
124
+ * parser.close -> code
125
+ *
126
+ * This method releases any resources allocated by the current instance
127
+ * changes the state to Closed and close any underlying input.
128
+ */
129
+ static VALUE
130
+ ruby_xml_reader_close(VALUE self)
131
+ {
132
+ return INT2FIX(xmlTextReaderClose(_SELF(self)));
133
+ }
134
+
135
+ /*
136
+ * call-seq:
137
+ * parser.move_to_attribute(val) -> code
138
+ *
139
+ * Move the position of the current instance to the attribute with the
140
+ * specified index (if +val+ is an integer) or name (if +val+ is a string)
141
+ * relative to the containing element.
142
+ */
143
+ static VALUE
144
+ ruby_xml_reader_move_to_attr(VALUE self, VALUE val)
145
+ {
146
+ xmlTextReaderPtr reader;
147
+ int ret;
148
+
149
+ reader = _SELF(self);
150
+
151
+ if (TYPE(val) == T_FIXNUM) {
152
+ ret = xmlTextReaderMoveToAttributeNo(reader, FIX2INT(val));
153
+ }
154
+ else {
155
+ ret = xmlTextReaderMoveToAttribute(reader, (const xmlChar *)RVAL2CSTR(val));
156
+ }
157
+
158
+ return INT2FIX(ret);
159
+ }
160
+
161
+ /*
162
+ * call-seq:
163
+ * reader.move_to_first_attribute -> code
164
+ *
165
+ * Move the position of the current instance to the first attribute associated
166
+ * with the current node.
167
+ */
168
+ static VALUE
169
+ ruby_xml_reader_move_to_first_attr(VALUE self)
170
+ {
171
+ return INT2FIX(xmlTextReaderMoveToFirstAttribute(_SELF(self)));
172
+ }
173
+
174
+ /*
175
+ * call-seq:
176
+ * reader.move_to_next_attribute -> code
177
+ *
178
+ * Move the position of the current instance to the next attribute associated
179
+ * with the current node.
180
+ */
181
+ static VALUE
182
+ ruby_xml_reader_move_to_next_attr(VALUE self)
183
+ {
184
+ return INT2FIX(xmlTextReaderMoveToNextAttribute(_SELF(self)));
185
+ }
186
+
187
+ /*
188
+ * call-seq:
189
+ * reader.move_to_element -> code
190
+ *
191
+ * Move the position of the current instance to the node that contains the
192
+ * current attribute node.
193
+ */
194
+ static VALUE
195
+ ruby_xml_reader_move_to_element(VALUE self)
196
+ {
197
+ return INT2FIX(xmlTextReaderMoveToElement(_SELF(self)));
198
+ }
199
+
200
+ /*
201
+ * call-seq:
202
+ * reader.next -> code
203
+ *
204
+ * Skip to the node following the current one in document order while avoiding
205
+ * the subtree if any.
206
+ */
207
+ static VALUE
208
+ ruby_xml_reader_next(VALUE self)
209
+ {
210
+ return INT2FIX(xmlTextReaderNext(_SELF(self)));
211
+ }
212
+
213
+ /*
214
+ * call-seq:
215
+ * reader.next_sibling -> code
216
+ *
217
+ * Skip to the node following the current one in document order while avoiding
218
+ * the subtree if any. Currently implemented only for Readers built on a
219
+ * document.
220
+ */
221
+ static VALUE
222
+ ruby_xml_reader_next_sibling(VALUE self)
223
+ {
224
+ return INT2FIX(xmlTextReaderNextSibling(_SELF(self)));
225
+ }
226
+
227
+ /*
228
+ * call-seq:
229
+ * reader.node_type -> type
230
+ *
231
+ * Get the node type of the current node. Reference:
232
+ * http://dotgnu.org/pnetlib-doc/System/Xml/XmlNodeType.html
233
+ */
234
+ static VALUE
235
+ ruby_xml_reader_node_type(VALUE self)
236
+ {
237
+ return INT2FIX(xmlTextReaderNodeType(_SELF(self)));
238
+ }
239
+
240
+ /*
241
+ * call-seq:
242
+ * reader.normalization -> value
243
+ *
244
+ * The value indicating whether to normalize white space and attribute values.
245
+ * Since attribute value and end of line normalizations are a MUST in the XML
246
+ * specification only the value true is accepted. The broken bahaviour of
247
+ * accepting out of range character entities like � is of course not
248
+ * supported either.
249
+ *
250
+ * Return 1 or -1 in case of error.
251
+ */
252
+ static VALUE
253
+ ruby_xml_reader_normalization(VALUE self)
254
+ {
255
+ return INT2FIX(xmlTextReaderNormalization(_SELF(self)));
256
+ }
257
+
258
+ /*
259
+ * call-seq:
260
+ * reader.read -> code
261
+ *
262
+ * Move the position of the current instance to the next node in the stream,
263
+ * exposing its properties.
264
+ *
265
+ * Return 1 if the node was read successfully, 0 if there is no more nodes to
266
+ * read, or -1 in case of error.
267
+ */
268
+ static VALUE
269
+ ruby_xml_reader_read(VALUE self)
270
+ {
271
+ return INT2FIX(xmlTextReaderRead(_SELF(self)));
272
+ }
273
+
274
+ /*
275
+ * call-seq:
276
+ * reader.read_attribute_value -> code
277
+ *
278
+ * Parse an attribute value into one or more Text and EntityReference nodes.
279
+ *
280
+ * Return 1 in case of success, 0 if the reader was not positionned on an
281
+ * attribute node or all the attribute values have been read, or -1 in case of
282
+ * error.
283
+ */
284
+ static VALUE
285
+ ruby_xml_reader_read_attr_value(VALUE self)
286
+ {
287
+ return INT2FIX(xmlTextReaderReadAttributeValue(_SELF(self)));
288
+ }
289
+
290
+ /*
291
+ * call-seq:
292
+ * reader.read_inner_xml -> data
293
+ *
294
+ * Read the contents of the current node, including child nodes and markup.
295
+ *
296
+ * Return a string containing the XML content, or nil if the current node is
297
+ * neither an element nor attribute, or has no child nodes.
298
+ */
299
+ static VALUE
300
+ ruby_xml_reader_read_inner_xml(VALUE self)
301
+ {
302
+ return CSTR2RVAL2(xmlTextReaderReadInnerXml(_SELF(self)));
303
+ }
304
+
305
+ /*
306
+ * call-seq:
307
+ * reader.read_outer_xml -> data
308
+ *
309
+ * Read the contents of the current node, including child nodes and markup.
310
+ *
311
+ * Return a string containing the XML content, or nil if the current node is
312
+ * neither an element nor attribute, or has no child nodes.
313
+ */
314
+ static VALUE
315
+ ruby_xml_reader_read_outer_xml(VALUE self)
316
+ {
317
+ return CSTR2RVAL2(xmlTextReaderReadOuterXml(_SELF(self)));
318
+ }
319
+
320
+ /*
321
+ * call-seq:
322
+ * reader.read_state -> state
323
+ *
324
+ * Get the read state of the reader.
325
+ */
326
+ static VALUE
327
+ ruby_xml_reader_read_state(VALUE self)
328
+ {
329
+ return INT2FIX(xmlTextReaderReadState(_SELF(self)));
330
+ }
331
+
332
+ /*
333
+ * call-seq:
334
+ * reader.read_string -> string
335
+ *
336
+ * Read the contents of an element or a text node as a string.
337
+ *
338
+ * Return a string containing the contents of the Element or Text node, or nil
339
+ * if the reader is positioned on any other type of node.
340
+ */
341
+ static VALUE
342
+ ruby_xml_reader_read_string(VALUE self)
343
+ {
344
+ return CSTR2RVAL2(xmlTextReaderReadString(_SELF(self)));
345
+ }
346
+
347
+ static void
348
+ __xml_reader_error_cb(void *arg,
349
+ const char *msg, xmlParserSeverities severity,
350
+ xmlTextReaderLocatorPtr locator)
351
+ {
352
+ VALUE reader;
353
+ VALUE block;
354
+
355
+ reader = (VALUE)arg;
356
+ block = rb_ivar_get(reader, error_handler_block_ivar_id);
357
+ if (NIL_P(block))
358
+ rb_bug("no ivar block");
359
+
360
+ rb_funcall(block,
361
+ rb_intern("call"),
362
+ 5,
363
+ reader,
364
+ CSTR2RVAL(msg),
365
+ INT2FIX(severity),
366
+ CSTR2RVAL2(xmlTextReaderLocatorBaseURI(locator)),
367
+ INT2FIX(xmlTextReaderLocatorLineNumber(locator)));
368
+ }
369
+
370
+ /*
371
+ * call-seq:
372
+ * reader.set_error_handler { ... }
373
+ *
374
+ * Register a callback block that will be called on error and warnings. The
375
+ * block will be called with 5 parameters: the reader, the error message, the
376
+ * severity, the base URI and the line number.
377
+ */
378
+ static VALUE
379
+ ruby_xml_reader_set_error_handler(VALUE self)
380
+ {
381
+ VALUE block;
382
+ xmlTextReaderPtr reader;
383
+
384
+ if (rb_block_given_p() == Qfalse)
385
+ rb_raise(rb_eRuntimeError, "No block given");
386
+
387
+ block = rb_block_proc();
388
+
389
+ /* Embed the block within the parser object to avoid it to be collected.
390
+ * Previous handler if exits is overwritten.
391
+ */
392
+ rb_ivar_set(self, error_handler_block_ivar_id, block);
393
+ reader = _SELF(self);
394
+ xmlTextReaderSetErrorHandler(reader, __xml_reader_error_cb, (void *)self);
395
+
396
+ return self;
397
+ }
398
+
399
+ /*
400
+ * call-seq:
401
+ * reader.reset_error_handler
402
+ *
403
+ * Restore the default error and warning handlers.
404
+ */
405
+ static VALUE
406
+ ruby_xml_reader_reset_error_handler(VALUE self)
407
+ {
408
+ xmlTextReaderSetErrorHandler(_SELF(self), NULL, NULL);
409
+ return self;
410
+ }
411
+
412
+ /*
413
+ * call-seq:
414
+ * reader.relax_ng_validate(rng) -> code
415
+ *
416
+ * Use RelaxNG to validate the document as it is processed. Activation is only
417
+ * possible before the first read. If +rng+ is nil, the RelaxNG validation is
418
+ * desactivated.
419
+ *
420
+ * Return 0 in case the RelaxNG validation could be (des)activated and -1 in
421
+ * case of error.
422
+ */
423
+ static VALUE
424
+ ruby_xml_reader_relax_ng_validate(VALUE self, VALUE rng)
425
+ {
426
+ return INT2FIX(xmlTextReaderRelaxNGValidate(_SELF(self), NIL_P(rng) ? NULL : RVAL2CSTR(rng)));
427
+ }
428
+
429
+ #if LIBXML_VERSION >= 20620
430
+ /*
431
+ * call-seq:
432
+ * reader.schema_validate(schema) -> code
433
+ *
434
+ * Use W3C XSD schema to validate the document as it is processed. Activation
435
+ * is only possible before the first read. If +schema+ is nil, then XML Schema
436
+ * validation is desactivated.
437
+ *
438
+ * Return 0 in case the schemas validation could be (de)activated and -1 in
439
+ * case of error.
440
+ */
441
+ static VALUE
442
+ ruby_xml_reader_schema_validate(VALUE self, VALUE xsd)
443
+ {
444
+ return INT2FIX(xmlTextReaderSchemaValidate(_SELF(self), NIL_P(xsd) ? NULL : RVAL2CSTR(xsd)));
445
+ }
446
+ #endif
447
+
448
+ /*
449
+ * call-seq:
450
+ * reader.name -> name
451
+ *
452
+ * Return the qualified name of the node.
453
+ */
454
+ static VALUE
455
+ ruby_xml_reader_name(VALUE self)
456
+ {
457
+ return CSTR2RVAL(xmlTextReaderConstName(_SELF(self)));
458
+ }
459
+
460
+ /*
461
+ * call-seq:
462
+ * reader.local_name -> name
463
+ *
464
+ * Return the local name of the node.
465
+ */
466
+ static VALUE
467
+ ruby_xml_reader_local_name(VALUE self)
468
+ {
469
+ return CSTR2RVAL(xmlTextReaderConstLocalName(_SELF(self)));
470
+ }
471
+
472
+ /*
473
+ * call-seq:
474
+ * reader.attribute_count -> count
475
+ *
476
+ * Provide the number of attributes of the current node.
477
+ */
478
+ static VALUE
479
+ ruby_xml_reader_attr_count(VALUE self)
480
+ {
481
+ return INT2FIX(xmlTextReaderAttributeCount(_SELF(self)));
482
+ }
483
+
484
+ /*
485
+ * call-seq:
486
+ * reader.encoding -> encoding
487
+ *
488
+ * Determine the encoding of the document being read.
489
+ */
490
+ static VALUE
491
+ ruby_xml_reader_encoding(VALUE self)
492
+ {
493
+ return CSTR2RVAL(xmlTextReaderConstEncoding(_SELF(self)));
494
+ }
495
+
496
+ /*
497
+ * call-seq:
498
+ * reader.base_uri -> URI
499
+ *
500
+ * Determine the base URI of the node.
501
+ */
502
+ static VALUE
503
+ ruby_xml_reader_base_uri(VALUE self)
504
+ {
505
+ return CSTR2RVAL(xmlTextReaderConstBaseUri(_SELF(self)));
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
+ ruby_xml_reader_namespace_uri(VALUE self)
516
+ {
517
+ return CSTR2RVAL(xmlTextReaderConstNamespaceUri(_SELF(self)));
518
+ }
519
+
520
+ /*
521
+ * call-seq:
522
+ * reader.value -> text
523
+ *
524
+ * Provide the text value of the node if present.
525
+ */
526
+ static VALUE
527
+ ruby_xml_reader_value(VALUE self)
528
+ {
529
+ return CSTR2RVAL(xmlTextReaderConstValue(_SELF(self)));
530
+ }
531
+
532
+ /*
533
+ * call-seq:
534
+ * reader.prefix -> prefix
535
+ *
536
+ * Get a shorthand reference to the namespace associated with the node.
537
+ */
538
+ static VALUE
539
+ ruby_xml_reader_prefix(VALUE self)
540
+ {
541
+ return CSTR2RVAL(xmlTextReaderConstPrefix(_SELF(self)));
542
+ }
543
+
544
+ /*
545
+ * call-seq:
546
+ * reader.depth -> depth
547
+ *
548
+ * Get the depth of the node in the tree.
549
+ */
550
+ static VALUE
551
+ ruby_xml_reader_depth(VALUE self)
552
+ {
553
+ return INT2FIX(xmlTextReaderDepth(_SELF(self)));
554
+ }
555
+
556
+ /*
557
+ * call-seq:
558
+ * reader.quote_char -> char
559
+ *
560
+ * Get the quotation mark character used to enclose the value of an attribute,
561
+ * as an integer value (and -1 in case of error).
562
+ */
563
+ static VALUE
564
+ ruby_xml_reader_quote_char(VALUE self)
565
+ {
566
+ return INT2FIX(xmlTextReaderQuoteChar(_SELF(self)));
567
+ }
568
+
569
+ /*
570
+ * call-seq:
571
+ * reader.standalone -> code
572
+ *
573
+ * Determine the standalone status of the document being read.
574
+ *
575
+ * Return 1 if the document was declared to be standalone, 0 if it was
576
+ * declared to be not standalone, or -1 if the document did not specify its
577
+ * standalone status or in case of error.
578
+ */
579
+ static VALUE
580
+ ruby_xml_reader_standalone(VALUE self)
581
+ {
582
+ return INT2FIX(xmlTextReaderStandalone(_SELF(self)));
583
+ }
584
+
585
+ /*
586
+ * call-seq:
587
+ * reader.xml_lang -> value
588
+ *
589
+ * Get the xml:lang scope within which the node resides.
590
+ */
591
+ static VALUE
592
+ ruby_xml_reader_xml_lang(VALUE self)
593
+ {
594
+ return CSTR2RVAL(xmlTextReaderConstXmlLang(_SELF(self)));
595
+ }
596
+
597
+ /*
598
+ * call-seq:
599
+ * reader.xml_version -> version
600
+ *
601
+ * Determine the XML version of the document being read.
602
+ */
603
+ static VALUE
604
+ ruby_xml_reader_xml_version(VALUE self)
605
+ {
606
+ return CSTR2RVAL(xmlTextReaderConstXmlVersion(_SELF(self)));
607
+ }
608
+
609
+ /*
610
+ * call-seq:
611
+ * reader.has_attributes? -> bool
612
+ *
613
+ * Get whether the node has attributes.
614
+ */
615
+ static VALUE
616
+ ruby_xml_reader_has_attributes(VALUE self)
617
+ {
618
+ return xmlTextReaderHasAttributes(_SELF(self)) ? Qtrue : Qfalse;
619
+ }
620
+
621
+ /*
622
+ * call-seq:
623
+ * reader.has_value? -> bool
624
+ *
625
+ * Get whether the node can have a text value.
626
+ */
627
+ static VALUE
628
+ ruby_xml_reader_has_value(VALUE self)
629
+ {
630
+ return xmlTextReaderHasValue(_SELF(self)) ? Qtrue : Qfalse;
631
+ }
632
+
633
+ /*
634
+ * call-seq:
635
+ * reader[key] -> value
636
+ *
637
+ * Provide the value of the attribute with the specified index (if +key+ is an
638
+ * integer) or with the specified name (if +key+ is a string) relative to the
639
+ * containing element, as a string.
640
+ */
641
+ static VALUE
642
+ ruby_xml_reader_attribute(VALUE self, VALUE key)
643
+ {
644
+ xmlTextReaderPtr reader;
645
+ xmlChar *attr;
646
+
647
+ reader = _SELF(self);
648
+
649
+ if (TYPE(key) == T_FIXNUM) {
650
+ attr = xmlTextReaderGetAttributeNo(reader, FIX2INT(key));
651
+ }
652
+ else {
653
+ attr = xmlTextReaderGetAttribute(reader, (const xmlChar *)RVAL2CSTR(key));
654
+ }
655
+ return CSTR2RVAL2(attr);
656
+ }
657
+
658
+ /*
659
+ * call-seq:
660
+ * reader.lookup_namespace(prefix) -> value
661
+ *
662
+ * Resolve a namespace prefix in the scope of the current element.
663
+ * To return the default namespace, specify nil as +prefix+.
664
+ */
665
+ static VALUE
666
+ ruby_xml_reader_lookup_namespace(VALUE self, VALUE prefix)
667
+ {
668
+ return CSTR2RVAL2(xmlTextReaderLookupNamespace(_SELF(self), (const xmlChar *)RVAL2CSTR(prefix)));
669
+ }
670
+
671
+ /*
672
+ * call-seq:
673
+ * reader.expand -> node
674
+ *
675
+ * Read the contents of the current node and the full subtree. It then makes
676
+ * the subtree available until the next read call.
677
+ *
678
+ * Return an XML::Node object, or nil in case of error.
679
+ */
680
+ static VALUE
681
+ ruby_xml_reader_expand(VALUE self)
682
+ {
683
+ xmlNodePtr node;
684
+
685
+ node = xmlTextReaderExpand(_SELF(self));
686
+ if (NIL_P(node))
687
+ return Qnil;
688
+
689
+ return ruby_xml_node2_wrap(cXMLNode, node);
690
+ }
691
+
692
+ #if LIBXML_VERSION >= 20618
693
+ /*
694
+ * call-seq:
695
+ * reader.byte_consumed -> value
696
+ *
697
+ * This method provides the current index of the parser used by the reader,
698
+ * relative to the start of the current entity.
699
+ */
700
+ static VALUE
701
+ ruby_xml_reader_byte_consumed(VALUE self)
702
+ {
703
+ return INT2NUM(xmlTextReaderByteConsumed(_SELF(self)));
704
+ }
705
+ #endif
706
+
707
+ #if LIBXML_VERSION >= 20617
708
+ /*
709
+ * call-seq:
710
+ * reader.column_number -> number
711
+ *
712
+ * Provide the column number of the current parsing point.
713
+ */
714
+ static VALUE
715
+ ruby_xml_reader_column_number(VALUE self)
716
+ {
717
+ return INT2NUM(xmlTextReaderGetParserColumnNumber(_SELF(self)));
718
+ }
719
+
720
+ /*
721
+ * call-seq:
722
+ * reader.line_number -> number
723
+ *
724
+ * Provide the line number of the current parsing point.
725
+ */
726
+ static VALUE
727
+ ruby_xml_reader_line_number(VALUE self)
728
+ {
729
+ return INT2NUM(xmlTextReaderGetParserLineNumber(_SELF(self)));
730
+ }
731
+ #endif
732
+
733
+ /*
734
+ * call-seq:
735
+ * reader.default? -> bool
736
+ *
737
+ * Return whether an Attribute node was generated from the default value
738
+ * defined in the DTD or schema.
739
+ */
740
+ static VALUE
741
+ ruby_xml_reader_default(VALUE self)
742
+ {
743
+ return xmlTextReaderIsDefault(_SELF(self)) ? Qtrue : Qfalse;
744
+ }
745
+
746
+ /*
747
+ * call-seq:
748
+ * reader.namespace_declaration? -> bool
749
+ *
750
+ * Determine whether the current node is a namespace declaration rather than a
751
+ * regular attribute.
752
+ */
753
+ static VALUE
754
+ ruby_xml_reader_namespace_declaration(VALUE self)
755
+ {
756
+ return xmlTextReaderIsNamespaceDecl(_SELF(self)) ? Qtrue : Qfalse;
757
+ }
758
+
759
+ /*
760
+ * call-seq:
761
+ * reader.empty_element? -> bool
762
+ *
763
+ * Check if the current node is empty.
764
+ */
765
+ static VALUE
766
+ ruby_xml_reader_empty_element(VALUE self)
767
+ {
768
+ return xmlTextReaderIsEmptyElement(_SELF(self)) ? Qtrue : Qfalse;
769
+ }
770
+
771
+ /*
772
+ * call-seq:
773
+ * reader.valid? -> bool
774
+ *
775
+ * Retrieve the validity status from the parser context.
776
+ */
777
+ static VALUE
778
+ ruby_xml_reader_valid(VALUE self)
779
+ {
780
+ return xmlTextReaderIsValid(_SELF(self)) ? Qtrue : Qfalse;
781
+ }
782
+
783
+ /* Rdoc needs to know. */
784
+ #ifdef RDOC_NEVER_DEFINED
785
+ mXML = rb_define_module("XML");
786
+ #endif
787
+
788
+ void
789
+ ruby_init_xml_reader(void)
790
+ {
791
+ cXMLReader = rb_define_class_under(mXML, "Reader", rb_cObject);
792
+ error_handler_block_ivar_id = rb_intern("@__error_handler_callback__");
793
+
794
+ rb_define_singleton_method(cXMLReader, "file", ruby_xml_reader_new_file, -1);
795
+ rb_define_singleton_method(cXMLReader, "walker", ruby_xml_reader_new_walker, 1);
796
+ rb_define_alias(CLASS_OF(cXMLReader), "document", "walker");
797
+ rb_define_singleton_method(cXMLReader, "new", ruby_xml_reader_new_data, -1);
798
+ rb_define_alias(CLASS_OF(cXMLReader), "string", "new");
799
+
800
+ rb_define_method(cXMLReader, "close", ruby_xml_reader_close, 0);
801
+
802
+ rb_define_method(cXMLReader, "move_to_attribute", ruby_xml_reader_move_to_attr, 1);
803
+ rb_define_method(cXMLReader, "move_to_first_attribute", ruby_xml_reader_move_to_first_attr, 0);
804
+ rb_define_method(cXMLReader, "move_to_next_attribute", ruby_xml_reader_move_to_next_attr, 0);
805
+ rb_define_method(cXMLReader, "move_to_element", ruby_xml_reader_move_to_element, 0);
806
+ rb_define_method(cXMLReader, "next", ruby_xml_reader_next, 0);
807
+ rb_define_method(cXMLReader, "next_sibling", ruby_xml_reader_next_sibling, 0);
808
+ rb_define_method(cXMLReader, "read", ruby_xml_reader_read, 0);
809
+ rb_define_method(cXMLReader, "read_attribute_value", ruby_xml_reader_read_attr_value, 0);
810
+ rb_define_method(cXMLReader, "read_inner_xml", ruby_xml_reader_read_inner_xml, 0);
811
+ rb_define_method(cXMLReader, "read_outer_xml", ruby_xml_reader_read_outer_xml, 0);
812
+ rb_define_method(cXMLReader, "read_state", ruby_xml_reader_read_state, 0);
813
+ rb_define_method(cXMLReader, "read_string", ruby_xml_reader_read_string, 0);
814
+
815
+ rb_define_method(cXMLReader, "set_error_handler", ruby_xml_reader_set_error_handler, 0);
816
+ rb_define_method(cXMLReader, "reset_error_handler", ruby_xml_reader_reset_error_handler, 0);
817
+
818
+ rb_define_method(cXMLReader, "relax_ng_validate", ruby_xml_reader_relax_ng_validate, 1);
819
+ #if LIBXML_VERSION >= 20620
820
+ rb_define_method(cXMLReader, "schema_validate", ruby_xml_reader_schema_validate, 1);
821
+ #endif
822
+
823
+ rb_define_method(cXMLReader, "node_type", ruby_xml_reader_node_type, 0);
824
+ rb_define_method(cXMLReader, "normalization", ruby_xml_reader_normalization, 0);
825
+ rb_define_method(cXMLReader, "attribute_count", ruby_xml_reader_attr_count, 0);
826
+ rb_define_method(cXMLReader, "name", ruby_xml_reader_name, 0);
827
+ rb_define_method(cXMLReader, "local_name", ruby_xml_reader_local_name, 0);
828
+ rb_define_method(cXMLReader, "encoding", ruby_xml_reader_encoding, 0);
829
+ rb_define_method(cXMLReader, "base_uri", ruby_xml_reader_base_uri, 0);
830
+ rb_define_method(cXMLReader, "namespace_uri", ruby_xml_reader_namespace_uri, 0);
831
+ rb_define_method(cXMLReader, "xml_lang", ruby_xml_reader_xml_lang, 0);
832
+ rb_define_method(cXMLReader, "xml_version", ruby_xml_reader_xml_version, 0);
833
+ rb_define_method(cXMLReader, "prefix", ruby_xml_reader_prefix, 0);
834
+ rb_define_method(cXMLReader, "depth", ruby_xml_reader_depth, 0);
835
+ rb_define_method(cXMLReader, "quote_char", ruby_xml_reader_quote_char, 0);
836
+ rb_define_method(cXMLReader, "standalone", ruby_xml_reader_standalone, 0);
837
+
838
+ rb_define_method(cXMLReader, "has_attributes?", ruby_xml_reader_has_attributes, 0);
839
+ rb_define_method(cXMLReader, "[]", ruby_xml_reader_attribute, 1);
840
+ rb_define_method(cXMLReader, "has_value?", ruby_xml_reader_has_value, 0);
841
+ rb_define_method(cXMLReader, "value", ruby_xml_reader_value, 0);
842
+
843
+ rb_define_method(cXMLReader, "lookup_namespace", ruby_xml_reader_lookup_namespace, 1);
844
+ rb_define_method(cXMLReader, "expand", ruby_xml_reader_expand, 0);
845
+
846
+ #if LIBXML_VERSION >= 20618
847
+ rb_define_method(cXMLReader, "byte_consumed", ruby_xml_reader_byte_consumed, 0);
848
+ #endif
849
+ #if LIBXML_VERSION >= 20617
850
+ rb_define_method(cXMLReader, "column_number", ruby_xml_reader_column_number, 0);
851
+ rb_define_method(cXMLReader, "line_number", ruby_xml_reader_line_number, 0);
852
+ #endif
853
+ rb_define_method(cXMLReader, "default?", ruby_xml_reader_default, 0);
854
+ rb_define_method(cXMLReader, "empty_element?", ruby_xml_reader_empty_element, 0);
855
+ rb_define_method(cXMLReader, "namespace_declaration?", ruby_xml_reader_namespace_declaration, 0);
856
+ rb_define_method(cXMLReader, "valid?", ruby_xml_reader_valid, 0);
857
+
858
+ rb_define_const(cXMLReader, "LOADDTD", INT2FIX(XML_PARSER_LOADDTD));
859
+ rb_define_const(cXMLReader, "DEFAULTATTRS", INT2FIX(XML_PARSER_DEFAULTATTRS));
860
+ rb_define_const(cXMLReader, "VALIDATE", INT2FIX(XML_PARSER_VALIDATE));
861
+ rb_define_const(cXMLReader, "SUBST_ENTITIES", INT2FIX(XML_PARSER_SUBST_ENTITIES));
862
+
863
+ rb_define_const(cXMLReader, "SEVERITY_VALIDITY_WARNING", INT2FIX(XML_PARSER_SEVERITY_VALIDITY_WARNING));
864
+ rb_define_const(cXMLReader, "SEVERITY_VALIDITY_ERROR", INT2FIX(XML_PARSER_SEVERITY_VALIDITY_ERROR));
865
+ rb_define_const(cXMLReader, "SEVERITY_WARNING", INT2FIX(XML_PARSER_SEVERITY_WARNING));
866
+ rb_define_const(cXMLReader, "SEVERITY_ERROR", INT2FIX(XML_PARSER_SEVERITY_ERROR));
867
+
868
+ rb_define_const(cXMLReader, "TYPE_NONE", INT2FIX(XML_READER_TYPE_NONE));
869
+ rb_define_const(cXMLReader, "TYPE_ELEMENT", INT2FIX(XML_READER_TYPE_ELEMENT));
870
+ rb_define_const(cXMLReader, "TYPE_ATTRIBUTE", INT2FIX(XML_READER_TYPE_ATTRIBUTE));
871
+ rb_define_const(cXMLReader, "TYPE_TEXT", INT2FIX(XML_READER_TYPE_TEXT));
872
+ rb_define_const(cXMLReader, "TYPE_CDATA", INT2FIX(XML_READER_TYPE_CDATA));
873
+ rb_define_const(cXMLReader, "TYPE_ENTITY_REFERENCE", INT2FIX(XML_READER_TYPE_ENTITY_REFERENCE));
874
+ rb_define_const(cXMLReader, "TYPE_ENTITY", INT2FIX(XML_READER_TYPE_ENTITY));
875
+ rb_define_const(cXMLReader, "TYPE_PROCESSING_INSTRUCTION", INT2FIX(XML_READER_TYPE_PROCESSING_INSTRUCTION));
876
+ rb_define_const(cXMLReader, "TYPE_COMMENT", INT2FIX(XML_READER_TYPE_COMMENT));
877
+ rb_define_const(cXMLReader, "TYPE_DOCUMENT", INT2FIX(XML_READER_TYPE_DOCUMENT));
878
+ rb_define_const(cXMLReader, "TYPE_DOCUMENT_TYPE", INT2FIX(XML_READER_TYPE_DOCUMENT_TYPE));
879
+ rb_define_const(cXMLReader, "TYPE_DOCUMENT_FRAGMENT", INT2FIX(XML_READER_TYPE_DOCUMENT_FRAGMENT));
880
+ rb_define_const(cXMLReader, "TYPE_NOTATION", INT2FIX(XML_READER_TYPE_NOTATION));
881
+ rb_define_const(cXMLReader, "TYPE_WHITESPACE", INT2FIX(XML_READER_TYPE_WHITESPACE));
882
+ rb_define_const(cXMLReader, "TYPE_SIGNIFICANT_WHITESPACE", INT2FIX(XML_READER_TYPE_SIGNIFICANT_WHITESPACE));
883
+ rb_define_const(cXMLReader, "TYPE_END_ELEMENT", INT2FIX(XML_READER_TYPE_END_ELEMENT));
884
+ rb_define_const(cXMLReader, "TYPE_END_ENTITY", INT2FIX(XML_READER_TYPE_END_ENTITY));
885
+ rb_define_const(cXMLReader, "TYPE_XML_DECLARATION", INT2FIX(XML_READER_TYPE_XML_DECLARATION));
886
+
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
+ }