libxml-ruby 0.9.8-x86-mswin32-60 → 0.9.9-x86-mswin32-60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. data/CHANGES +41 -1
  2. data/LICENSE +3 -4
  3. data/README +37 -24
  4. data/Rakefile +2 -2
  5. data/ext/libxml/extconf.rb +31 -12
  6. data/ext/libxml/libxml.c +56 -858
  7. data/ext/libxml/ruby_libxml.h +93 -96
  8. data/ext/libxml/ruby_xml.c +855 -0
  9. data/ext/libxml/ruby_xml.h +9 -0
  10. data/ext/libxml/ruby_xml_attr.c +3 -9
  11. data/ext/libxml/ruby_xml_attr.h +2 -2
  12. data/ext/libxml/ruby_xml_attr_decl.c +2 -8
  13. data/ext/libxml/ruby_xml_attr_decl.h +1 -1
  14. data/ext/libxml/ruby_xml_attributes.c +6 -8
  15. data/ext/libxml/ruby_xml_attributes.h +1 -1
  16. data/ext/libxml/ruby_xml_document.c +915 -895
  17. data/ext/libxml/ruby_xml_document.h +2 -2
  18. data/ext/libxml/ruby_xml_dtd.c +257 -136
  19. data/ext/libxml/ruby_xml_dtd.h +1 -1
  20. data/ext/libxml/ruby_xml_encoding.c +55 -37
  21. data/ext/libxml/ruby_xml_encoding.h +1 -1
  22. data/ext/libxml/ruby_xml_error.c +526 -1058
  23. data/ext/libxml/ruby_xml_error.h +1 -1
  24. data/ext/libxml/ruby_xml_html_parser.c +2 -8
  25. data/ext/libxml/ruby_xml_html_parser.h +2 -2
  26. data/ext/libxml/ruby_xml_html_parser_context.c +175 -145
  27. data/ext/libxml/ruby_xml_html_parser_context.h +1 -1
  28. data/ext/libxml/ruby_xml_html_parser_options.c +12 -20
  29. data/ext/libxml/ruby_xml_html_parser_options.h +1 -1
  30. data/ext/libxml/ruby_xml_input_cbg.c +2 -8
  31. data/ext/libxml/ruby_xml_input_cbg.h +1 -1
  32. data/ext/libxml/ruby_xml_namespace.c +2 -8
  33. data/ext/libxml/ruby_xml_namespace.h +2 -2
  34. data/ext/libxml/ruby_xml_namespaces.c +1 -9
  35. data/ext/libxml/ruby_xml_namespaces.h +1 -1
  36. data/ext/libxml/ruby_xml_node.c +182 -121
  37. data/ext/libxml/ruby_xml_node.h +2 -2
  38. data/ext/libxml/ruby_xml_parser.c +2 -8
  39. data/ext/libxml/ruby_xml_parser.h +2 -2
  40. data/ext/libxml/ruby_xml_parser_context.c +952 -901
  41. data/ext/libxml/ruby_xml_parser_context.h +2 -2
  42. data/ext/libxml/ruby_xml_parser_options.c +2 -9
  43. data/ext/libxml/ruby_xml_parser_options.h +1 -1
  44. data/ext/libxml/ruby_xml_reader.c +1002 -993
  45. data/ext/libxml/ruby_xml_reader.h +1 -1
  46. data/ext/libxml/ruby_xml_relaxng.c +1 -7
  47. data/ext/libxml/ruby_xml_relaxng.h +1 -1
  48. data/ext/libxml/ruby_xml_sax2_handler.c +2 -2
  49. data/ext/libxml/ruby_xml_sax2_handler.h +1 -1
  50. data/ext/libxml/ruby_xml_sax_parser.c +2 -8
  51. data/ext/libxml/ruby_xml_sax_parser.h +2 -2
  52. data/ext/libxml/ruby_xml_schema.c +1 -7
  53. data/ext/libxml/ruby_xml_schema.h +1 -1
  54. data/ext/libxml/{version.h → ruby_xml_version.h} +2 -2
  55. data/ext/libxml/ruby_xml_xinclude.c +2 -8
  56. data/ext/libxml/ruby_xml_xinclude.h +2 -2
  57. data/ext/libxml/ruby_xml_xpath.c +17 -18
  58. data/ext/libxml/ruby_xml_xpath.h +2 -2
  59. data/ext/libxml/ruby_xml_xpath_context.c +387 -389
  60. data/ext/libxml/ruby_xml_xpath_context.h +2 -2
  61. data/ext/libxml/ruby_xml_xpath_expression.c +18 -8
  62. data/ext/libxml/ruby_xml_xpath_expression.h +1 -1
  63. data/ext/libxml/ruby_xml_xpath_object.c +19 -8
  64. data/ext/libxml/ruby_xml_xpath_object.h +1 -1
  65. data/ext/libxml/ruby_xml_xpointer.c +2 -8
  66. data/ext/libxml/ruby_xml_xpointer.h +2 -2
  67. data/ext/mingw/libxml_ruby.dll.a +0 -0
  68. data/ext/mingw/libxml_ruby.so +0 -0
  69. data/ext/vc/libxml_ruby.sln +7 -1
  70. data/lib/libxml.rb +1 -12
  71. data/lib/libxml/attr.rb +0 -3
  72. data/lib/libxml/attr_decl.rb +0 -3
  73. data/lib/libxml/attributes.rb +0 -3
  74. data/lib/libxml/document.rb +31 -5
  75. data/lib/libxml/error.rb +8 -4
  76. data/lib/libxml/properties.rb +0 -5
  77. data/lib/libxml/sax_callbacks.rb +30 -19
  78. data/lib/libxml/tree.rb +0 -1
  79. data/lib/libxml/xpath_object.rb +0 -13
  80. data/test/model/definition.dtd +8 -0
  81. data/test/tc_attributes.rb +4 -1
  82. data/test/tc_document.rb +16 -0
  83. data/test/tc_dtd.rb +30 -2
  84. data/test/tc_html_parser.rb +55 -10
  85. data/test/tc_node.rb +67 -1
  86. data/test/tc_node_edit.rb +26 -6
  87. data/test/tc_node_text.rb +41 -23
  88. data/test/tc_parser.rb +50 -0
  89. data/test/tc_reader.rb +15 -0
  90. data/test/tc_relaxng.rb +1 -1
  91. data/test/tc_sax_parser.rb +37 -5
  92. data/test/tc_schema.rb +1 -1
  93. data/test/tc_xpath.rb +1 -0
  94. data/test/tc_xpath_expression.rb +4 -2
  95. metadata +6 -6
  96. data/ext/libxml/ruby_xml_state.c +0 -51
  97. data/ext/libxml/ruby_xml_state.h +0 -11
  98. data/ext/vc/libxml_ruby.vcproj +0 -460
@@ -0,0 +1,9 @@
1
+ /* Please see the LICENSE file for copyright and distribution information */
2
+
3
+ #ifndef __RUBY_XML_H__
4
+ #define __RUBY_XML_H__
5
+
6
+ extern VALUE mXML;
7
+ void rxml_init_xml(void);
8
+
9
+ #endif
@@ -1,11 +1,11 @@
1
- /* $Id: ruby_xml_attr.c 739 2009-01-23 03:42:09Z cfis $ */
1
+ /* $Id: ruby_xml_attr.c 758 2009-01-25 20:36:03Z cfis $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
5
5
  /*
6
6
  * Document-class: LibXML::XML::Attr
7
7
  *
8
- * Provides access to an single element attribute.
8
+ * Provides access to an attribute defined on an element.
9
9
  *
10
10
  * Basic Usage:
11
11
  *
@@ -327,13 +327,7 @@ VALUE rxml_attr_value_set(VALUE self, VALUE val)
327
327
  return (self);
328
328
  }
329
329
 
330
- // Rdoc needs to know
331
- #ifdef RDOC_NEVER_DEFINED
332
- mLibXML = rb_define_module("LibXML");
333
- mXML = rb_define_module_under(mLibXML, "XML");
334
- #endif
335
-
336
- void ruby_init_xml_attr(void)
330
+ void rxml_init_attr(void)
337
331
  {
338
332
  cXMLAttr = rb_define_class_under(mXML, "Attr", rb_cObject);
339
333
  rb_define_alloc_func(cXMLAttr, rxml_attr_alloc);
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_attr.h 712 2009-01-20 08:08:52Z cfis $ */
1
+ /* $Id: ruby_xml_attr.h 758 2009-01-25 20:36:03Z cfis $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -7,7 +7,7 @@
7
7
 
8
8
  extern VALUE cXMLAttr;
9
9
 
10
- void ruby_init_xml_attr(void);
10
+ void rxml_init_attr(void);
11
11
  VALUE rxml_attr_wrap(xmlAttrPtr xattr);
12
12
  VALUE rxml_attr_value_get(VALUE self);
13
13
  VALUE rxml_attr_value_set(VALUE self, VALUE val);
@@ -8,7 +8,7 @@
8
8
  * At attribute declaration is used in XML::Dtds to define
9
9
  * what attributes are allowed on an element. An attribute
10
10
  * declaration defines an attribues name, data type and default
11
- * value (if any).
11
+ * value (if any).
12
12
  */
13
13
 
14
14
  #include "ruby_libxml.h"
@@ -158,13 +158,7 @@ VALUE rxml_attr_decl_value_get(VALUE self)
158
158
  return Qnil;
159
159
  }
160
160
 
161
- // Rdoc needs to know
162
- #ifdef RDOC_NEVER_DEFINED
163
- mLibXML = rb_define_module("LibXML");
164
- mXML = rb_define_module_under(mLibXML, "XML");
165
- #endif
166
-
167
- void ruby_init_xml_attr_decl(void)
161
+ void rxml_init_attr_decl(void)
168
162
  {
169
163
  cXMLAttrDecl = rb_define_class_under(mXML, "AttrDecl", rb_cObject);
170
164
  rb_define_method(cXMLAttrDecl, "doc", rxml_attr_decl_doc_get, 0);
@@ -7,7 +7,7 @@
7
7
 
8
8
  extern VALUE cXMLAttrDecl;
9
9
 
10
- void ruby_init_xml_attr_decl(void);
10
+ void rxml_init_attr_decl(void);
11
11
  VALUE rxml_attr_decl_wrap(xmlAttributePtr xattribute);
12
12
  VALUE rxml_attr_decl_value_get(VALUE self);
13
13
  #endif
@@ -199,9 +199,13 @@ static VALUE rxml_attributes_each(VALUE self)
199
199
 
200
200
  while (xattr)
201
201
  {
202
+ /* Get the next attribute while we still can - the user
203
+ may remove the yielded attribute. */
204
+ xmlAttrPtr next = xattr->next;
205
+
202
206
  VALUE attr = rxml_attr_wrap(xattr);
203
207
  rb_yield(attr);
204
- xattr = xattr->next;
208
+ xattr = next;
205
209
  }
206
210
 
207
211
  return self;
@@ -258,13 +262,7 @@ static VALUE rxml_attributes_first(VALUE self)
258
262
  return Qnil;
259
263
  }
260
264
 
261
- // Rdoc needs to know
262
- #ifdef RDOC_NEVER_DEFINED
263
- mLibXML = rb_define_module("LibXML");
264
- mXML = rb_define_module_under(mLibXML, "XML");
265
- #endif
266
-
267
- void ruby_init_xml_attributes(void)
265
+ void rxml_init_attributes(void)
268
266
  {
269
267
  cXMLAttributes = rb_define_class_under(mXML, "Attributes", rb_cObject);
270
268
  rb_include_module(cXMLAttributes, rb_mEnumerable);
@@ -7,7 +7,7 @@
7
7
 
8
8
  extern VALUE cXMLAttributesibutes;
9
9
 
10
- void ruby_init_xml_attributes(void);
10
+ void rxml_init_attributes(void);
11
11
  VALUE rxml_attributes_new(xmlNodePtr xnode);
12
12
 
13
13
  VALUE rxml_attributes_attribute_get(VALUE self, VALUE name);
@@ -1,895 +1,915 @@
1
- /* $Id: ruby_xml_document.c 735 2009-01-22 20:00:04Z cfis $ */
2
-
3
- /*
4
- * Document-class: LibXML::XML::Document
5
- *
6
- * The XML::Document class provides a tree based API for working
7
- * with xml documents. You may directly create a document and
8
- * manipulate it, or create a document from a data source by
9
- * using an XML::Parser object.
10
- *
11
- * To create a document from scratch:
12
- *
13
- * doc = XML::Document.new()
14
- * doc.root = XML::Node.new('root_node')
15
- * doc.root << XML::Node.new('elem1')
16
- * doc.save(filename, :indent => true, :encoding => 'UTF-8')
17
- *
18
- * To read a document from a file:
19
- *
20
- * doc = XML::Document.file('my_file')
21
- *
22
- * To use a parser to read a document:
23
- *
24
- * parser = XML::Parser.new
25
- * parser.file = 'my_file'
26
- * doc = parser.parse
27
- *
28
- * To write a file:
29
- *
30
- *
31
- * doc = XML::Document.new()
32
- * doc.root = XML::Node.new('root_node')
33
- * root = doc.root
34
- *
35
- * root << elem1 = XML::Node.new('elem1')
36
- * elem1['attr1'] = 'val1'
37
- * elem1['attr2'] = 'val2'
38
- *
39
- * root << elem2 = XML::Node.new('elem2')
40
- * elem2['attr1'] = 'val1'
41
- * elem2['attr2'] = 'val2'
42
- *
43
- * root << elem3 = XML::Node.new('elem3')
44
- * elem3 << elem4 = XML::Node.new('elem4')
45
- * elem3 << elem5 = XML::Node.new('elem5')
46
- *
47
- * elem5 << elem6 = XML::Node.new('elem6')
48
- * elem6 << 'Content for element 6'
49
- *
50
- * elem3['attr'] = 'baz'
51
- *
52
- * doc.save(filename, :indent => true, :encoding => 'UTF-8')
53
- */
54
-
55
- #include <stdarg.h>
56
- #include <st.h>
57
- #include "ruby_libxml.h"
58
- #include "ruby_xml_document.h"
59
-
60
- VALUE cXMLDocument;
61
-
62
-
63
- void rxml_document_free(xmlDocPtr xdoc)
64
- {
65
- xdoc->_private = NULL;
66
- xmlFreeDoc(xdoc);
67
- }
68
-
69
- void rxml_document_mark(xmlDocPtr xdoc)
70
- {
71
- rb_gc_mark(LIBXML_STATE);
72
- }
73
-
74
- VALUE rxml_document_wrap(xmlDocPtr xdoc)
75
- {
76
- VALUE result;
77
-
78
- // This node is already wrapped
79
- if (xdoc->_private != NULL)
80
- {
81
- result = (VALUE) xdoc->_private;
82
- }
83
- else
84
- {
85
- result = Data_Wrap_Struct(cXMLDocument, rxml_document_mark,
86
- rxml_document_free, xdoc);
87
- xdoc->_private = (void*) result;
88
- }
89
-
90
- return result;
91
- }
92
-
93
- static void LibXML_validity_warning(void * ctxt, const char * msg, va_list ap)
94
- {
95
- if (rb_block_given_p())
96
- {
97
- char buff[1024];
98
- snprintf(buff, 1024, msg, ap);
99
- rb_yield(rb_ary_new3(2, rb_str_new2(buff), Qfalse));
100
- }
101
- else
102
- {
103
- fprintf(stderr, "warning -- found validity error: ");
104
- fprintf(stderr, msg, ap);
105
- }
106
- }
107
-
108
- /*
109
- * call-seq:
110
- * XML::Document.alloc(xml_version = 1.0) -> document
111
- *
112
- * Alocates a new XML::Document, optionally specifying the
113
- * XML version.
114
- */
115
- static VALUE rxml_document_alloc(VALUE klass)
116
- {
117
- return Data_Wrap_Struct(klass, rxml_document_mark, rxml_document_free, NULL);
118
- }
119
-
120
- /*
121
- * call-seq:
122
- * XML::Document.initialize(xml_version = 1.0) -> document
123
- *
124
- * Initializes a new XML::Document, optionally specifying the
125
- * XML version.
126
- */
127
- static VALUE rxml_document_initialize(int argc, VALUE *argv, VALUE self)
128
- {
129
- xmlDocPtr xdoc;
130
- VALUE xmlver;
131
-
132
- switch (argc)
133
- {
134
- case 0:
135
- xmlver = rb_str_new2("1.0");
136
- break;
137
- case 1:
138
- rb_scan_args(argc, argv, "01", &xmlver);
139
- break;
140
- default:
141
- rb_raise(rb_eArgError, "wrong number of arguments (need 0 or 1)");
142
- }
143
-
144
- Check_Type(xmlver, T_STRING);
145
- xdoc = xmlNewDoc((xmlChar*) StringValuePtr(xmlver));
146
- xdoc->_private = (void*) self;
147
- DATA_PTR( self) = xdoc;
148
-
149
- return self;
150
- }
151
-
152
- /*
153
- * call-seq:
154
- * document.compression -> num
155
- *
156
- * Obtain this document's compression mode identifier.
157
- */
158
- static VALUE rxml_document_compression_get(VALUE self)
159
- {
160
- #ifdef HAVE_ZLIB_H
161
- xmlDocPtr xdoc;
162
-
163
- int compmode;
164
- Data_Get_Struct(self, xmlDoc, xdoc);
165
-
166
- compmode = xmlGetDocCompressMode(xdoc);
167
- if (compmode == -1)
168
- return(Qnil);
169
- else
170
- return(INT2NUM(compmode));
171
- #else
172
- rb_warn("libxml not compiled with zlib support");
173
- return (Qfalse);
174
- #endif
175
- }
176
-
177
- /*
178
- * call-seq:
179
- * document.compression = num
180
- *
181
- * Set this document's compression mode.
182
- */
183
- static VALUE rxml_document_compression_set(VALUE self, VALUE num)
184
- {
185
- #ifdef HAVE_ZLIB_H
186
- xmlDocPtr xdoc;
187
-
188
- int compmode;
189
- Check_Type(num, T_FIXNUM);
190
- Data_Get_Struct(self, xmlDoc, xdoc);
191
-
192
- if (xdoc == NULL)
193
- {
194
- return(Qnil);
195
- }
196
- else
197
- {
198
- xmlSetDocCompressMode(xdoc, NUM2INT(num));
199
-
200
- compmode = xmlGetDocCompressMode(xdoc);
201
- if (compmode == -1)
202
- return(Qnil);
203
- else
204
- return(INT2NUM(compmode));
205
- }
206
- #else
207
- rb_warn("libxml compiled without zlib support");
208
- return (Qfalse);
209
- #endif
210
- }
211
-
212
- /*
213
- * call-seq:
214
- * document.compression? -> (true|false)
215
- *
216
- * Determine whether this document is compressed.
217
- */
218
- static VALUE rxml_document_compression_q(VALUE self)
219
- {
220
- #ifdef HAVE_ZLIB_H
221
- xmlDocPtr xdoc;
222
-
223
- Data_Get_Struct(self, xmlDoc, xdoc);
224
-
225
- if (xdoc->compression != -1)
226
- return(Qtrue);
227
- else
228
- return(Qfalse);
229
- #else
230
- rb_warn("libxml compiled without zlib support");
231
- return (Qfalse);
232
- #endif
233
- }
234
-
235
- /*
236
- * call-seq:
237
- * document.child -> node
238
- *
239
- * Get this document's child node.
240
- */
241
- static VALUE rxml_document_child_get(VALUE self)
242
- {
243
- xmlDocPtr xdoc;
244
- Data_Get_Struct(self, xmlDoc, xdoc);
245
-
246
- if (xdoc->children == NULL)
247
- return (Qnil);
248
-
249
- return rxml_node_wrap(xdoc->children);
250
- }
251
-
252
- /*
253
- * call-seq:
254
- * document.child? -> (true|false)
255
- *
256
- * Determine whether this document has a child node.
257
- */
258
- static VALUE rxml_document_child_q(VALUE self)
259
- {
260
- xmlDocPtr xdoc;
261
- Data_Get_Struct(self, xmlDoc, xdoc);
262
-
263
- if (xdoc->children == NULL)
264
- return (Qfalse);
265
- else
266
- return (Qtrue);
267
- }
268
-
269
-
270
- /*
271
- * call-seq:
272
- * node.debug -> true|false
273
- *
274
- * Print libxml debugging information to stdout.
275
- * Requires that libxml was compiled with debugging enabled.
276
- */
277
- static VALUE rxml_document_debug(VALUE self)
278
- {
279
- #ifdef LIBXML_DEBUG_ENABLED
280
- xmlDocPtr xdoc;
281
- Data_Get_Struct(self, xmlDoc, xdoc);
282
- xmlDebugDumpDocument(NULL, xdoc);
283
- return Qtrue;
284
- #else
285
- rb_warn("libxml was compiled without debugging support.")
286
- return Qfalse;
287
- #endif
288
- }
289
-
290
- /*
291
- * call-seq:
292
- * document.encoding -> XML::Encoding::UTF_8
293
- *
294
- * Obtain the encoding specified by this document.
295
- */
296
- static VALUE rxml_document_encoding_get(VALUE self)
297
- {
298
- xmlDocPtr xdoc;
299
- Data_Get_Struct(self, xmlDoc, xdoc);
300
-
301
- return INT2NUM(xmlParseCharEncoding(xdoc->encoding));
302
- }
303
-
304
- /*
305
- * call-seq:
306
- * document.encoding = XML::Encoding::UTF_8
307
- *
308
- * Set the encoding for this document.
309
- */
310
- static VALUE rxml_document_encoding_set(VALUE self, VALUE encoding)
311
- {
312
- xmlDocPtr xdoc;
313
- const char* xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(encoding));
314
-
315
- Data_Get_Struct(self, xmlDoc, xdoc);
316
-
317
- if (xdoc->encoding != NULL)
318
- xmlFree((xmlChar *) xdoc->encoding);
319
-
320
- xdoc->encoding = xmlStrdup((xmlChar *)xencoding);
321
- return self;
322
- }
323
-
324
- /*
325
- * call-seq:
326
- * document.last -> node
327
- *
328
- * Obtain the last node.
329
- */
330
- static VALUE rxml_document_last_get(VALUE self)
331
- {
332
- xmlDocPtr xdoc;
333
-
334
- Data_Get_Struct(self, xmlDoc, xdoc);
335
-
336
- if (xdoc->last == NULL)
337
- return (Qnil);
338
-
339
- return rxml_node_wrap(xdoc->last);
340
- }
341
-
342
- /*
343
- * call-seq:
344
- * document.last? -> (true|false)
345
- *
346
- * Determine whether there is a last node.
347
- */
348
- static VALUE rxml_document_last_q(VALUE self)
349
- {
350
- xmlDocPtr xdoc;
351
-
352
- Data_Get_Struct(self, xmlDoc, xdoc);
353
-
354
- if (xdoc->last == NULL)
355
- return (Qfalse);
356
- else
357
- return (Qtrue);
358
- }
359
-
360
- /*
361
- * call-seq:
362
- * document.next -> node
363
- *
364
- * Obtain the next node.
365
- */
366
- static VALUE rxml_document_next_get(VALUE self)
367
- {
368
- xmlDocPtr xdoc;
369
-
370
- Data_Get_Struct(self, xmlDoc, xdoc);
371
-
372
- if (xdoc->next == NULL)
373
- return (Qnil);
374
-
375
- return rxml_node_wrap(xdoc->next);
376
- }
377
-
378
- /*
379
- * call-seq:
380
- * document.next? -> (true|false)
381
- *
382
- * Determine whether there is a next node.
383
- */
384
- static VALUE rxml_document_next_q(VALUE self)
385
- {
386
- xmlDocPtr xdoc;
387
-
388
- Data_Get_Struct(self, xmlDoc, xdoc);
389
-
390
- if (xdoc->next == NULL)
391
- return (Qfalse);
392
- else
393
- return (Qtrue);
394
- }
395
-
396
- /*
397
- * call-seq:
398
- * document.parent -> node
399
- *
400
- * Obtain the parent node.
401
- */
402
- static VALUE rxml_document_parent_get(VALUE self)
403
- {
404
- xmlDocPtr xdoc;
405
-
406
- Data_Get_Struct(self, xmlDoc, xdoc);
407
-
408
- if (xdoc->parent == NULL)
409
- return (Qnil);
410
-
411
- return rxml_node_wrap(xdoc->parent);
412
- }
413
-
414
- /*
415
- * call-seq:
416
- * document.parent? -> (true|false)
417
- *
418
- * Determine whether there is a parent node.
419
- */
420
- static VALUE rxml_document_parent_q(VALUE self)
421
- {
422
- xmlDocPtr xdoc;
423
-
424
- Data_Get_Struct(self, xmlDoc, xdoc);
425
-
426
- if (xdoc->parent == NULL)
427
- return (Qfalse);
428
- else
429
- return (Qtrue);
430
- }
431
-
432
- /*
433
- * call-seq:
434
- * document.prev -> node
435
- *
436
- * Obtain the previous node.
437
- */
438
- static VALUE rxml_document_prev_get(VALUE self)
439
- {
440
- xmlDocPtr xdoc;
441
-
442
- Data_Get_Struct(self, xmlDoc, xdoc);
443
-
444
- if (xdoc->prev == NULL)
445
- return (Qnil);
446
-
447
- return rxml_node_wrap(xdoc->prev);
448
- }
449
-
450
- /*
451
- * call-seq:
452
- * document.prev? -> (true|false)
453
- *
454
- * Determine whether there is a previous node.
455
- */
456
- static VALUE rxml_document_prev_q(VALUE self)
457
- {
458
- xmlDocPtr xdoc;
459
-
460
- Data_Get_Struct(self, xmlDoc, xdoc);
461
-
462
- if (xdoc->prev == NULL)
463
- return (Qfalse);
464
- else
465
- return (Qtrue);
466
- }
467
-
468
- /*
469
- * call-seq:
470
- * document.root -> node
471
- *
472
- * Obtain the root node.
473
- */
474
- static VALUE rxml_document_root_get(VALUE self)
475
- {
476
- xmlDocPtr xdoc;
477
-
478
- xmlNodePtr root;
479
-
480
- Data_Get_Struct(self, xmlDoc, xdoc);
481
- root = xmlDocGetRootElement(xdoc);
482
-
483
- if (root == NULL)
484
- return (Qnil);
485
-
486
- return rxml_node_wrap(root);
487
- }
488
-
489
- /*
490
- * call-seq:
491
- * document.root = node
492
- *
493
- * Set the root node.
494
- */
495
- static VALUE rxml_document_root_set(VALUE self, VALUE node)
496
- {
497
- xmlDocPtr xdoc;
498
- xmlNodePtr xroot, xnode;
499
-
500
- if (rb_obj_is_kind_of(node, cXMLNode) == Qfalse)
501
- rb_raise(rb_eTypeError, "must pass an XML::Node type object");
502
-
503
- Data_Get_Struct(self, xmlDoc, xdoc);
504
- Data_Get_Struct(node, xmlNode, xnode);
505
- xroot = xmlDocSetRootElement(xdoc, xnode);
506
- if (xroot == NULL)
507
- return (Qnil);
508
-
509
- return rxml_node_wrap(xroot);
510
- }
511
-
512
- /*
513
- * call-seq:
514
- * document.save(filename) -> int
515
- * document.save(filename, :indent => true, :encoding => 'UTF-8') -> int
516
- *
517
- * Saves a document to a file. You may provide an optional hash table
518
- * to control how the string is generated. Valid options are:
519
- *
520
- * :indent - Specifies if the string should be indented. The default value
521
- * is true. Note that indentation is only added if both :indent is
522
- * true and XML.indent_tree_output is true. If :indent is set to false,
523
- * then both indentation and line feeds are removed from the result.
524
- *
525
- * :encoding - Specifies the output encoding of the string. It
526
- * defaults to the original encoding of the document (see
527
- * #encoding. To override the orginal encoding, use one of the
528
- * XML::Encoding encoding constants. */
529
- static VALUE rxml_document_save(int argc, VALUE *argv, VALUE self)
530
- {
531
- VALUE options = Qnil;
532
- VALUE filename = Qnil;
533
- xmlDocPtr xdoc;
534
- int indent = 1;
535
- const char *xfilename;
536
- const char *xencoding;
537
- int length;
538
-
539
- rb_scan_args(argc, argv, "11", &filename, &options);
540
-
541
- Check_Type(filename, T_STRING);
542
- xfilename = StringValuePtr(filename);
543
-
544
- Data_Get_Struct(self, xmlDoc, xdoc);
545
- xencoding = xdoc->encoding;
546
-
547
- if (!NIL_P(options))
548
- {
549
- VALUE rencoding, rindent;
550
- Check_Type(options, T_HASH);
551
- rencoding = rb_hash_aref(options, ID2SYM(rb_intern("encoding")));
552
- rindent = rb_hash_aref(options, ID2SYM(rb_intern("indent")));
553
-
554
- if (rindent == Qfalse)
555
- indent = 0;
556
-
557
- if (rencoding != Qnil)
558
- {
559
- xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(rencoding));
560
- if (!xencoding)
561
- rb_raise(rb_eArgError, "Unknown encoding value: %d", NUM2INT(rencoding));
562
- }
563
- }
564
-
565
- length = xmlSaveFormatFileEnc(xfilename, xdoc, xencoding, indent);
566
-
567
- if (length == -1)
568
- rxml_raise(&xmlLastError);
569
-
570
- return (INT2NUM(length));
571
- }
572
-
573
- /*
574
- * call-seq:
575
- * document.standalone? -> (true|false)
576
- *
577
- * Determine whether this is a standalone document.
578
- */
579
- static VALUE rxml_document_standalone_q(VALUE self)
580
- {
581
- xmlDocPtr xdoc;
582
-
583
- Data_Get_Struct(self, xmlDoc, xdoc);
584
- if (xdoc->standalone)
585
- return (Qtrue);
586
- else
587
- return (Qfalse);
588
- }
589
-
590
- /*
591
- * call-seq:
592
- * document.to_s -> "string"
593
- * document.to_s(:indent => true, :encoding => 'UTF-8') -> "string"
594
- *
595
- * Converts a document, and all of its children, to a string representation.
596
- * You may provide an optional hash table to control how the string is
597
- * generated. Valid options are:
598
- *
599
- * :indent - Specifies if the string should be indented. The default value
600
- * is true. Note that indentation is only added if both :indent is
601
- * true and XML.indent_tree_output is true. If :indent is set to false,
602
- * then both indentation and line feeds are removed from the result.
603
- *
604
- * :encoding - Specifies the output encoding of the string. It
605
- * defaults to XML::Encoding::UTF8. To change it, use one of the
606
- * XML::Encoding encoding constants. */
607
- static VALUE rxml_document_to_s(int argc, VALUE *argv, VALUE self)
608
- {
609
- VALUE result;
610
- VALUE options = Qnil;
611
- xmlDocPtr xdoc;
612
- int indent = 1;
613
- const char *xencoding = "UTF-8";
614
- xmlChar *buffer;
615
- int length;
616
-
617
- rb_scan_args(argc, argv, "01", &options);
618
-
619
- if (!NIL_P(options))
620
- {
621
- VALUE rencoding, rindent;
622
- Check_Type(options, T_HASH);
623
- rencoding = rb_hash_aref(options, ID2SYM(rb_intern("encoding")));
624
- rindent = rb_hash_aref(options, ID2SYM(rb_intern("indent")));
625
-
626
- if (rindent == Qfalse)
627
- indent = 0;
628
-
629
- if (rencoding != Qnil)
630
- {
631
- xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(rencoding));
632
- if (!xencoding)
633
- rb_raise(rb_eArgError, "Unknown encoding value: %d", NUM2INT(rencoding));
634
- }
635
- }
636
-
637
- Data_Get_Struct(self, xmlDoc, xdoc);
638
- xmlDocDumpFormatMemoryEnc(xdoc, &buffer, &length, xencoding, indent);
639
-
640
- result = rb_str_new((const char*) buffer, length);
641
- xmlFree(buffer);
642
- return result;
643
- }
644
-
645
- /*
646
- * call-seq:
647
- * document.url -> "url"
648
- *
649
- * Obtain this document's source URL, if any.
650
- */
651
- static VALUE rxml_document_url_get(VALUE self)
652
- {
653
- xmlDocPtr xdoc;
654
-
655
- Data_Get_Struct(self, xmlDoc, xdoc);
656
- if (xdoc->URL == NULL)
657
- return (Qnil);
658
- else
659
- return (rb_str_new2((const char*) xdoc->URL));
660
- }
661
-
662
- /*
663
- * call-seq:
664
- * document.version -> "version"
665
- *
666
- * Obtain the XML version specified by this document.
667
- */
668
- static VALUE rxml_document_version_get(VALUE self)
669
- {
670
- xmlDocPtr xdoc;
671
-
672
- Data_Get_Struct(self, xmlDoc, xdoc);
673
- if (xdoc->version == NULL)
674
- return (Qnil);
675
- else
676
- return (rb_str_new2((const char*) xdoc->version));
677
- }
678
-
679
- /*
680
- * call-seq:
681
- * document.xinclude -> num
682
- *
683
- * Process xinclude directives in this document.
684
- */
685
- static VALUE rxml_document_xinclude(VALUE self)
686
- {
687
- #ifdef LIBXML_XINCLUDE_ENABLED
688
- xmlDocPtr xdoc;
689
-
690
- int ret;
691
-
692
- Data_Get_Struct(self, xmlDoc, xdoc);
693
- ret = xmlXIncludeProcess(xdoc);
694
- if (ret >= 0)
695
- {
696
- return(INT2NUM(ret));
697
- }
698
- else
699
- {
700
- rxml_raise(&xmlLastError);
701
- return Qnil;
702
- }
703
- #else
704
- rb_warn(
705
- "libxml was compiled without XInclude support. Please recompile libxml and ruby-libxml");
706
- return (Qfalse);
707
- #endif
708
- }
709
-
710
- void LibXML_validity_error(void * ctxt, const char * msg, va_list ap)
711
- {
712
- if (rb_block_given_p())
713
- {
714
- char buff[1024];
715
- snprintf(buff, 1024, msg, ap);
716
- rb_yield(rb_ary_new3(2, rb_str_new2(buff), Qtrue));
717
- }
718
- else
719
- {
720
- fprintf(stderr, "error -- found validity error: ");
721
- fprintf(stderr, msg, ap);
722
- }
723
- }
724
-
725
- /*
726
- * call-seq:
727
- * document.order_elements!
728
- *
729
- * Call this routine to speed up XPath computation on static documents.
730
- * This stamps all the element nodes with the document order.
731
- */
732
- static VALUE rxml_document_order_elements(VALUE self)
733
- {
734
- xmlDocPtr xdoc;
735
-
736
- Data_Get_Struct(self, xmlDoc, xdoc);
737
- return LONG2FIX(xmlXPathOrderDocElems(xdoc));
738
- }
739
-
740
- /*
741
- * call-seq:
742
- * document.validate_schema(schema) -> (true|false)
743
- *
744
- * Validate this document against the specified XML::Schema.
745
- *
746
- * If a block is provided it is used as an error handler for validaten errors.
747
- * The block is called with two argument, the message and a flag indication
748
- * if the message is an error (true) or a warning (false).
749
- */
750
- static VALUE rxml_document_validate_schema(VALUE self, VALUE schema)
751
- {
752
- xmlSchemaValidCtxtPtr vptr;
753
- xmlDocPtr xdoc;
754
- xmlSchemaPtr xschema;
755
- int is_invalid;
756
-
757
- Data_Get_Struct(self, xmlDoc, xdoc);
758
- Data_Get_Struct(schema, xmlSchema, xschema);
759
-
760
- vptr = xmlSchemaNewValidCtxt(xschema);
761
-
762
- xmlSchemaSetValidErrors(vptr,
763
- (xmlSchemaValidityErrorFunc) LibXML_validity_error,
764
- (xmlSchemaValidityWarningFunc) LibXML_validity_warning, NULL);
765
-
766
- is_invalid = xmlSchemaValidateDoc(vptr, xdoc);
767
- xmlSchemaFreeValidCtxt(vptr);
768
- if (is_invalid)
769
- {
770
- rxml_raise(&xmlLastError);
771
- return Qfalse;
772
- }
773
- else
774
- {
775
- return Qtrue;
776
- }
777
- }
778
-
779
- /*
780
- * call-seq:
781
- * document.validate_schema(relaxng) -> (true|false)
782
- *
783
- * Validate this document against the specified XML::RelaxNG.
784
- *
785
- * If a block is provided it is used as an error handler for validaten errors.
786
- * The block is called with two argument, the message and a flag indication
787
- * if the message is an error (true) or a warning (false).
788
- */
789
- static VALUE rxml_document_validate_relaxng(VALUE self, VALUE relaxng)
790
- {
791
- xmlRelaxNGValidCtxtPtr vptr;
792
- xmlDocPtr xdoc;
793
- xmlRelaxNGPtr xrelaxng;
794
- int is_invalid;
795
-
796
- Data_Get_Struct(self, xmlDoc, xdoc);
797
- Data_Get_Struct(relaxng, xmlRelaxNG, xrelaxng);
798
-
799
- vptr = xmlRelaxNGNewValidCtxt(xrelaxng);
800
-
801
- xmlRelaxNGSetValidErrors(vptr,
802
- (xmlRelaxNGValidityErrorFunc) LibXML_validity_error,
803
- (xmlRelaxNGValidityWarningFunc) LibXML_validity_warning, NULL);
804
-
805
- is_invalid = xmlRelaxNGValidateDoc(vptr, xdoc);
806
- xmlRelaxNGFreeValidCtxt(vptr);
807
- if (is_invalid)
808
- {
809
- rxml_raise(&xmlLastError);
810
- return Qfalse;
811
- }
812
- else
813
- {
814
- return Qtrue;
815
- }
816
- }
817
-
818
- /*
819
- * call-seq:
820
- * document.validate(dtd) -> (true|false)
821
- *
822
- * Validate this document against the specified XML::DTD.
823
- */
824
- static VALUE rxml_document_validate_dtd(VALUE self, VALUE dtd)
825
- {
826
- VALUE error = Qnil;
827
- xmlValidCtxt ctxt;
828
- xmlDocPtr xdoc;
829
- xmlDtdPtr xdtd;
830
-
831
- Data_Get_Struct(self, xmlDoc, xdoc);
832
- Data_Get_Struct(dtd, xmlDtd, xdtd);
833
-
834
- ctxt.userData = &error;
835
- ctxt.error = (xmlValidityErrorFunc) LibXML_validity_error;
836
- ctxt.warning = (xmlValidityWarningFunc) LibXML_validity_warning;
837
-
838
- ctxt.nodeNr = 0;
839
- ctxt.nodeTab = NULL;
840
- ctxt.vstateNr = 0;
841
- ctxt.vstateTab = NULL;
842
-
843
- if (xmlValidateDtd(&ctxt, xdoc, xdtd))
844
- {
845
- return (Qtrue);
846
- }
847
- else
848
- {
849
- rxml_raise(&xmlLastError);
850
- return Qfalse;
851
- }
852
- }
853
-
854
-
855
- // Rdoc needs to know
856
- #ifdef RDOC_NEVER_DEFINED
857
- mLibXML = rb_define_module("LibXML");
858
- mXML = rb_define_module_under(mLibXML, "XML");
859
- #endif
860
-
861
- void ruby_init_xml_document(void)
862
- {
863
- cXMLDocument = rb_define_class_under(mXML, "Document", rb_cObject);
864
- rb_define_alloc_func(cXMLDocument, rxml_document_alloc);
865
-
866
- rb_define_method(cXMLDocument, "initialize", rxml_document_initialize, -1);
867
- rb_define_method(cXMLDocument, "child", rxml_document_child_get, 0);
868
- rb_define_method(cXMLDocument, "child?", rxml_document_child_q, 0);
869
- rb_define_method(cXMLDocument, "compression", rxml_document_compression_get, 0);
870
- rb_define_method(cXMLDocument, "compression=", rxml_document_compression_set, 1);
871
- rb_define_method(cXMLDocument, "compression?", rxml_document_compression_q, 0);
872
- rb_define_method(cXMLDocument, "debug", rxml_document_debug, 0);
873
- rb_define_method(cXMLDocument, "encoding", rxml_document_encoding_get, 0);
874
- rb_define_method(cXMLDocument, "encoding=", rxml_document_encoding_set, 1);
875
- rb_define_method(cXMLDocument, "last", rxml_document_last_get, 0);
876
- rb_define_method(cXMLDocument, "last?", rxml_document_last_q, 0);
877
- rb_define_method(cXMLDocument, "next", rxml_document_next_get, 0);
878
- rb_define_method(cXMLDocument, "next?", rxml_document_next_q, 0);
879
- rb_define_method(cXMLDocument, "order_elements!", rxml_document_order_elements, 0);
880
- rb_define_method(cXMLDocument, "parent", rxml_document_parent_get, 0);
881
- rb_define_method(cXMLDocument, "parent?", rxml_document_parent_q, 0);
882
- rb_define_method(cXMLDocument, "prev", rxml_document_prev_get, 0);
883
- rb_define_method(cXMLDocument, "prev?", rxml_document_prev_q, 0);
884
- rb_define_method(cXMLDocument, "root", rxml_document_root_get, 0);
885
- rb_define_method(cXMLDocument, "root=", rxml_document_root_set, 1);
886
- rb_define_method(cXMLDocument, "save", rxml_document_save, -1);
887
- rb_define_method(cXMLDocument, "standalone?", rxml_document_standalone_q, 0);
888
- rb_define_method(cXMLDocument, "to_s", rxml_document_to_s, -1);
889
- rb_define_method(cXMLDocument, "url", rxml_document_url_get, 0);
890
- rb_define_method(cXMLDocument, "version", rxml_document_version_get, 0);
891
- rb_define_method(cXMLDocument, "xinclude", rxml_document_xinclude, 0);
892
- rb_define_method(cXMLDocument, "validate", rxml_document_validate_dtd, 1);
893
- rb_define_method(cXMLDocument, "validate_schema", rxml_document_validate_schema, 1);
894
- rb_define_method(cXMLDocument, "validate_relaxng", rxml_document_validate_relaxng, 1);
895
- }
1
+ /* $Id: ruby_xml_document.c 804 2009-03-05 08:30:56Z cfis $ */
2
+
3
+ /*
4
+ * Document-class: LibXML::XML::Document
5
+ *
6
+ * The XML::Document class provides a tree based API for working
7
+ * with xml documents. You may directly create a document and
8
+ * manipulate it, or create a document from a data source by
9
+ * using an XML::Parser object.
10
+ *
11
+ * To read a document from a file:
12
+ *
13
+ * doc = XML::Document.file('my_file')
14
+ *
15
+ * To use a parser to read a document:
16
+ *
17
+ * parser = XML::Parser.file('my_file')
18
+ * doc = parser.parse
19
+ *
20
+ * To create a document from scratch:
21
+ *
22
+ * doc = XML::Document.new()
23
+ * doc.root = XML::Node.new('root_node')
24
+ * doc.root << XML::Node.new('elem1')
25
+ * doc.save(filename, :indent => true, :encoding => 'UTF-8')
26
+ *
27
+ * To write a document to a file:
28
+ *
29
+ * doc = XML::Document.new()
30
+ * doc.root = XML::Node.new('root_node')
31
+ * root = doc.root
32
+ *
33
+ * root << elem1 = XML::Node.new('elem1')
34
+ * elem1['attr1'] = 'val1'
35
+ * elem1['attr2'] = 'val2'
36
+ *
37
+ * root << elem2 = XML::Node.new('elem2')
38
+ * elem2['attr1'] = 'val1'
39
+ * elem2['attr2'] = 'val2'
40
+ *
41
+ * root << elem3 = XML::Node.new('elem3')
42
+ * elem3 << elem4 = XML::Node.new('elem4')
43
+ * elem3 << elem5 = XML::Node.new('elem5')
44
+ *
45
+ * elem5 << elem6 = XML::Node.new('elem6')
46
+ * elem6 << 'Content for element 6'
47
+ *
48
+ * elem3['attr'] = 'baz'
49
+ *
50
+ * doc.save(filename, :indent => true, :encoding => 'UTF-8')
51
+ */
52
+
53
+ #include <stdarg.h>
54
+ #include "ruby_libxml.h"
55
+ #include "ruby_xml_document.h"
56
+
57
+ VALUE cXMLDocument;
58
+
59
+
60
+ void rxml_document_free(xmlDocPtr xdoc)
61
+ {
62
+ xdoc->_private = NULL;
63
+ xmlFreeDoc(xdoc);
64
+ }
65
+
66
+ VALUE rxml_document_wrap(xmlDocPtr xdoc)
67
+ {
68
+ VALUE result;
69
+
70
+ // This node is already wrapped
71
+ if (xdoc->_private != NULL)
72
+ {
73
+ result = (VALUE) xdoc->_private;
74
+ }
75
+ else
76
+ {
77
+ result = Data_Wrap_Struct(cXMLDocument, NULL, rxml_document_free, xdoc);
78
+ xdoc->_private = (void*) result;
79
+ }
80
+
81
+ return result;
82
+ }
83
+
84
+ static void LibXML_validity_warning(void * ctxt, const char * msg, va_list ap)
85
+ {
86
+ if (rb_block_given_p())
87
+ {
88
+ char buff[1024];
89
+ snprintf(buff, 1024, msg, ap);
90
+ rb_yield(rb_ary_new3(2, rb_str_new2(buff), Qfalse));
91
+ }
92
+ else
93
+ {
94
+ fprintf(stderr, "warning -- found validity error: ");
95
+ fprintf(stderr, msg, ap);
96
+ }
97
+ }
98
+
99
+ /*
100
+ * call-seq:
101
+ * XML::Document.alloc(xml_version = 1.0) -> document
102
+ *
103
+ * Alocates a new XML::Document, optionally specifying the
104
+ * XML version.
105
+ */
106
+ static VALUE rxml_document_alloc(VALUE klass)
107
+ {
108
+ return Data_Wrap_Struct(klass, NULL, rxml_document_free, NULL);
109
+ }
110
+
111
+ /*
112
+ * call-seq:
113
+ * XML::Document.initialize(xml_version = 1.0) -> document
114
+ *
115
+ * Initializes a new XML::Document, optionally specifying the
116
+ * XML version.
117
+ */
118
+ static VALUE rxml_document_initialize(int argc, VALUE *argv, VALUE self)
119
+ {
120
+ xmlDocPtr xdoc;
121
+ VALUE xmlver;
122
+
123
+ switch (argc)
124
+ {
125
+ case 0:
126
+ xmlver = rb_str_new2("1.0");
127
+ break;
128
+ case 1:
129
+ rb_scan_args(argc, argv, "01", &xmlver);
130
+ break;
131
+ default:
132
+ rb_raise(rb_eArgError, "wrong number of arguments (need 0 or 1)");
133
+ }
134
+
135
+ Check_Type(xmlver, T_STRING);
136
+ xdoc = xmlNewDoc((xmlChar*) StringValuePtr(xmlver));
137
+ xdoc->_private = (void*) self;
138
+ DATA_PTR(self) = xdoc;
139
+
140
+ return self;
141
+ }
142
+
143
+ /*
144
+ * call-seq:
145
+ * document.compression -> num
146
+ *
147
+ * Obtain this document's compression mode identifier.
148
+ */
149
+ static VALUE rxml_document_compression_get(VALUE self)
150
+ {
151
+ #ifdef HAVE_ZLIB_H
152
+ xmlDocPtr xdoc;
153
+
154
+ int compmode;
155
+ Data_Get_Struct(self, xmlDoc, xdoc);
156
+
157
+ compmode = xmlGetDocCompressMode(xdoc);
158
+ if (compmode == -1)
159
+ return(Qnil);
160
+ else
161
+ return(INT2NUM(compmode));
162
+ #else
163
+ rb_warn("libxml not compiled with zlib support");
164
+ return (Qfalse);
165
+ #endif
166
+ }
167
+
168
+ /*
169
+ * call-seq:
170
+ * document.compression = num
171
+ *
172
+ * Set this document's compression mode.
173
+ */
174
+ static VALUE rxml_document_compression_set(VALUE self, VALUE num)
175
+ {
176
+ #ifdef HAVE_ZLIB_H
177
+ xmlDocPtr xdoc;
178
+
179
+ int compmode;
180
+ Check_Type(num, T_FIXNUM);
181
+ Data_Get_Struct(self, xmlDoc, xdoc);
182
+
183
+ if (xdoc == NULL)
184
+ {
185
+ return(Qnil);
186
+ }
187
+ else
188
+ {
189
+ xmlSetDocCompressMode(xdoc, NUM2INT(num));
190
+
191
+ compmode = xmlGetDocCompressMode(xdoc);
192
+ if (compmode == -1)
193
+ return(Qnil);
194
+ else
195
+ return(INT2NUM(compmode));
196
+ }
197
+ #else
198
+ rb_warn("libxml compiled without zlib support");
199
+ return (Qfalse);
200
+ #endif
201
+ }
202
+
203
+ /*
204
+ * call-seq:
205
+ * document.compression? -> (true|false)
206
+ *
207
+ * Determine whether this document is compressed.
208
+ */
209
+ static VALUE rxml_document_compression_q(VALUE self)
210
+ {
211
+ #ifdef HAVE_ZLIB_H
212
+ xmlDocPtr xdoc;
213
+
214
+ Data_Get_Struct(self, xmlDoc, xdoc);
215
+
216
+ if (xdoc->compression != -1)
217
+ return(Qtrue);
218
+ else
219
+ return(Qfalse);
220
+ #else
221
+ rb_warn("libxml compiled without zlib support");
222
+ return (Qfalse);
223
+ #endif
224
+ }
225
+
226
+ /*
227
+ * call-seq:
228
+ * document.child -> node
229
+ *
230
+ * Get this document's child node.
231
+ */
232
+ static VALUE rxml_document_child_get(VALUE self)
233
+ {
234
+ xmlDocPtr xdoc;
235
+ Data_Get_Struct(self, xmlDoc, xdoc);
236
+
237
+ if (xdoc->children == NULL)
238
+ return (Qnil);
239
+
240
+ return rxml_node_wrap(xdoc->children);
241
+ }
242
+
243
+ /*
244
+ * call-seq:
245
+ * document.child? -> (true|false)
246
+ *
247
+ * Determine whether this document has a child node.
248
+ */
249
+ static VALUE rxml_document_child_q(VALUE self)
250
+ {
251
+ xmlDocPtr xdoc;
252
+ Data_Get_Struct(self, xmlDoc, xdoc);
253
+
254
+ if (xdoc->children == NULL)
255
+ return (Qfalse);
256
+ else
257
+ return (Qtrue);
258
+ }
259
+
260
+
261
+ /*
262
+ * call-seq:
263
+ * node.debug -> true|false
264
+ *
265
+ * Print libxml debugging information to stdout.
266
+ * Requires that libxml was compiled with debugging enabled.
267
+ */
268
+ static VALUE rxml_document_debug(VALUE self)
269
+ {
270
+ #ifdef LIBXML_DEBUG_ENABLED
271
+ xmlDocPtr xdoc;
272
+ Data_Get_Struct(self, xmlDoc, xdoc);
273
+ xmlDebugDumpDocument(NULL, xdoc);
274
+ return Qtrue;
275
+ #else
276
+ rb_warn("libxml was compiled without debugging support.")
277
+ return Qfalse;
278
+ #endif
279
+ }
280
+
281
+ /*
282
+ * call-seq:
283
+ * document.encoding -> XML::Encoding::UTF_8
284
+ *
285
+ * Obtain the encoding specified by this document.
286
+ */
287
+ static VALUE rxml_document_encoding_get(VALUE self)
288
+ {
289
+ xmlDocPtr xdoc;
290
+ const char *xencoding;
291
+ Data_Get_Struct(self, xmlDoc, xdoc);
292
+
293
+ xencoding = (const char*)xdoc->encoding;
294
+ return INT2NUM(xmlParseCharEncoding(xencoding));
295
+ }
296
+
297
+ /*
298
+ * call-seq:
299
+ * document.encoding = XML::Encoding::UTF_8
300
+ *
301
+ * Set the encoding for this document.
302
+ */
303
+ static VALUE rxml_document_encoding_set(VALUE self, VALUE encoding)
304
+ {
305
+ xmlDocPtr xdoc;
306
+ const char* xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(encoding));
307
+
308
+ Data_Get_Struct(self, xmlDoc, xdoc);
309
+
310
+ if (xdoc->encoding != NULL)
311
+ xmlFree((xmlChar *) xdoc->encoding);
312
+
313
+ xdoc->encoding = xmlStrdup((xmlChar *)xencoding);
314
+ return self;
315
+ }
316
+
317
+ /*
318
+ * call-seq:
319
+ * document.last -> node
320
+ *
321
+ * Obtain the last node.
322
+ */
323
+ static VALUE rxml_document_last_get(VALUE self)
324
+ {
325
+ xmlDocPtr xdoc;
326
+
327
+ Data_Get_Struct(self, xmlDoc, xdoc);
328
+
329
+ if (xdoc->last == NULL)
330
+ return (Qnil);
331
+
332
+ return rxml_node_wrap(xdoc->last);
333
+ }
334
+
335
+ /*
336
+ * call-seq:
337
+ * document.last? -> (true|false)
338
+ *
339
+ * Determine whether there is a last node.
340
+ */
341
+ static VALUE rxml_document_last_q(VALUE self)
342
+ {
343
+ xmlDocPtr xdoc;
344
+
345
+ Data_Get_Struct(self, xmlDoc, xdoc);
346
+
347
+ if (xdoc->last == NULL)
348
+ return (Qfalse);
349
+ else
350
+ return (Qtrue);
351
+ }
352
+
353
+ /*
354
+ * call-seq:
355
+ * document.next -> node
356
+ *
357
+ * Obtain the next node.
358
+ */
359
+ static VALUE rxml_document_next_get(VALUE self)
360
+ {
361
+ xmlDocPtr xdoc;
362
+
363
+ Data_Get_Struct(self, xmlDoc, xdoc);
364
+
365
+ if (xdoc->next == NULL)
366
+ return (Qnil);
367
+
368
+ return rxml_node_wrap(xdoc->next);
369
+ }
370
+
371
+ /*
372
+ * call-seq:
373
+ * document.next? -> (true|false)
374
+ *
375
+ * Determine whether there is a next node.
376
+ */
377
+ static VALUE rxml_document_next_q(VALUE self)
378
+ {
379
+ xmlDocPtr xdoc;
380
+
381
+ Data_Get_Struct(self, xmlDoc, xdoc);
382
+
383
+ if (xdoc->next == NULL)
384
+ return (Qfalse);
385
+ else
386
+ return (Qtrue);
387
+ }
388
+
389
+ /*
390
+ * call-seq:
391
+ * node.type -> num
392
+ *
393
+ * Obtain this node's type identifier.
394
+ */
395
+ static VALUE rxml_document_node_type(VALUE self)
396
+ {
397
+ xmlNodePtr xnode;
398
+ Data_Get_Struct(self, xmlNode, xnode);
399
+ return (INT2NUM(xnode->type));
400
+ }
401
+
402
+ /*
403
+ * call-seq:
404
+ * document.parent -> node
405
+ *
406
+ * Obtain the parent node.
407
+ */
408
+ static VALUE rxml_document_parent_get(VALUE self)
409
+ {
410
+ xmlDocPtr xdoc;
411
+
412
+ Data_Get_Struct(self, xmlDoc, xdoc);
413
+
414
+ if (xdoc->parent == NULL)
415
+ return (Qnil);
416
+
417
+ return rxml_node_wrap(xdoc->parent);
418
+ }
419
+
420
+ /*
421
+ * call-seq:
422
+ * document.parent? -> (true|false)
423
+ *
424
+ * Determine whether there is a parent node.
425
+ */
426
+ static VALUE rxml_document_parent_q(VALUE self)
427
+ {
428
+ xmlDocPtr xdoc;
429
+
430
+ Data_Get_Struct(self, xmlDoc, xdoc);
431
+
432
+ if (xdoc->parent == NULL)
433
+ return (Qfalse);
434
+ else
435
+ return (Qtrue);
436
+ }
437
+
438
+ /*
439
+ * call-seq:
440
+ * document.prev -> node
441
+ *
442
+ * Obtain the previous node.
443
+ */
444
+ static VALUE rxml_document_prev_get(VALUE self)
445
+ {
446
+ xmlDocPtr xdoc;
447
+
448
+ Data_Get_Struct(self, xmlDoc, xdoc);
449
+
450
+ if (xdoc->prev == NULL)
451
+ return (Qnil);
452
+
453
+ return rxml_node_wrap(xdoc->prev);
454
+ }
455
+
456
+ /*
457
+ * call-seq:
458
+ * document.prev? -> (true|false)
459
+ *
460
+ * Determine whether there is a previous node.
461
+ */
462
+ static VALUE rxml_document_prev_q(VALUE self)
463
+ {
464
+ xmlDocPtr xdoc;
465
+
466
+ Data_Get_Struct(self, xmlDoc, xdoc);
467
+
468
+ if (xdoc->prev == NULL)
469
+ return (Qfalse);
470
+ else
471
+ return (Qtrue);
472
+ }
473
+
474
+ /*
475
+ * call-seq:
476
+ * document.root -> node
477
+ *
478
+ * Obtain the root node.
479
+ */
480
+ static VALUE rxml_document_root_get(VALUE self)
481
+ {
482
+ xmlDocPtr xdoc;
483
+
484
+ xmlNodePtr root;
485
+
486
+ Data_Get_Struct(self, xmlDoc, xdoc);
487
+ root = xmlDocGetRootElement(xdoc);
488
+
489
+ if (root == NULL)
490
+ return (Qnil);
491
+
492
+ return rxml_node_wrap(root);
493
+ }
494
+
495
+ /*
496
+ * call-seq:
497
+ * document.root = node
498
+ *
499
+ * Set the root node.
500
+ */
501
+ static VALUE rxml_document_root_set(VALUE self, VALUE node)
502
+ {
503
+ xmlDocPtr xdoc;
504
+ xmlNodePtr xroot, xnode;
505
+
506
+ if (rb_obj_is_kind_of(node, cXMLNode) == Qfalse)
507
+ rb_raise(rb_eTypeError, "must pass an XML::Node type object");
508
+
509
+ Data_Get_Struct(self, xmlDoc, xdoc);
510
+ Data_Get_Struct(node, xmlNode, xnode);
511
+
512
+ xroot = xmlDocSetRootElement(xdoc, xnode);
513
+ if (xroot == NULL)
514
+ return (Qnil);
515
+
516
+ return rxml_node_wrap(xroot);
517
+ }
518
+
519
+ /*
520
+ * call-seq:
521
+ * document.save(filename) -> int
522
+ * document.save(filename, :indent => true, :encoding => 'UTF-8') -> int
523
+ *
524
+ * Saves a document to a file. You may provide an optional hash table
525
+ * to control how the string is generated. Valid options are:
526
+ *
527
+ * :indent - Specifies if the string should be indented. The default value
528
+ * is true. Note that indentation is only added if both :indent is
529
+ * true and XML.indent_tree_output is true. If :indent is set to false,
530
+ * then both indentation and line feeds are removed from the result.
531
+ *
532
+ * :encoding - Specifies the output encoding of the string. It
533
+ * defaults to the original encoding of the document (see
534
+ * #encoding. To override the orginal encoding, use one of the
535
+ * XML::Encoding encoding constants. */
536
+ static VALUE rxml_document_save(int argc, VALUE *argv, VALUE self)
537
+ {
538
+ VALUE options = Qnil;
539
+ VALUE filename = Qnil;
540
+ xmlDocPtr xdoc;
541
+ int indent = 1;
542
+ const char *xfilename;
543
+ const char *xencoding;
544
+ int length;
545
+
546
+ rb_scan_args(argc, argv, "11", &filename, &options);
547
+
548
+ Check_Type(filename, T_STRING);
549
+ xfilename = StringValuePtr(filename);
550
+
551
+ Data_Get_Struct(self, xmlDoc, xdoc);
552
+ xencoding = xdoc->encoding;
553
+
554
+ if (!NIL_P(options))
555
+ {
556
+ VALUE rencoding, rindent;
557
+ Check_Type(options, T_HASH);
558
+ rencoding = rb_hash_aref(options, ID2SYM(rb_intern("encoding")));
559
+ rindent = rb_hash_aref(options, ID2SYM(rb_intern("indent")));
560
+
561
+ if (rindent == Qfalse)
562
+ indent = 0;
563
+
564
+ if (rencoding != Qnil)
565
+ {
566
+ xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(rencoding));
567
+ if (!xencoding)
568
+ rb_raise(rb_eArgError, "Unknown encoding value: %d", NUM2INT(rencoding));
569
+ }
570
+ }
571
+
572
+ length = xmlSaveFormatFileEnc(xfilename, xdoc, xencoding, indent);
573
+
574
+ if (length == -1)
575
+ rxml_raise(&xmlLastError);
576
+
577
+ return (INT2NUM(length));
578
+ }
579
+
580
+ /*
581
+ * call-seq:
582
+ * document.standalone? -> (true|false)
583
+ *
584
+ * Determine whether this is a standalone document.
585
+ */
586
+ static VALUE rxml_document_standalone_q(VALUE self)
587
+ {
588
+ xmlDocPtr xdoc;
589
+
590
+ Data_Get_Struct(self, xmlDoc, xdoc);
591
+ if (xdoc->standalone)
592
+ return (Qtrue);
593
+ else
594
+ return (Qfalse);
595
+ }
596
+
597
+ /*
598
+ * call-seq:
599
+ * document.to_s -> "string"
600
+ * document.to_s(:indent => true, :encoding => 'UTF-8') -> "string"
601
+ *
602
+ * Converts a document, and all of its children, to a string representation.
603
+ * You may provide an optional hash table to control how the string is
604
+ * generated. Valid options are:
605
+ *
606
+ * :indent - Specifies if the string should be indented. The default value
607
+ * is true. Note that indentation is only added if both :indent is
608
+ * true and XML.indent_tree_output is true. If :indent is set to false,
609
+ * then both indentation and line feeds are removed from the result.
610
+ *
611
+ * :encoding - Specifies the output encoding of the string. It
612
+ * defaults to XML::Encoding::UTF8. To change it, use one of the
613
+ * XML::Encoding encoding constants. */
614
+ static VALUE rxml_document_to_s(int argc, VALUE *argv, VALUE self)
615
+ {
616
+ VALUE result;
617
+ VALUE options = Qnil;
618
+ xmlDocPtr xdoc;
619
+ int indent = 1;
620
+ const char *xencoding = "UTF-8";
621
+ xmlChar *buffer;
622
+ int length;
623
+
624
+ rb_scan_args(argc, argv, "01", &options);
625
+
626
+ if (!NIL_P(options))
627
+ {
628
+ VALUE rencoding, rindent;
629
+ Check_Type(options, T_HASH);
630
+ rencoding = rb_hash_aref(options, ID2SYM(rb_intern("encoding")));
631
+ rindent = rb_hash_aref(options, ID2SYM(rb_intern("indent")));
632
+
633
+ if (rindent == Qfalse)
634
+ indent = 0;
635
+
636
+ if (rencoding != Qnil)
637
+ {
638
+ xencoding = xmlGetCharEncodingName((xmlCharEncoding)NUM2INT(rencoding));
639
+ if (!xencoding)
640
+ rb_raise(rb_eArgError, "Unknown encoding value: %d", NUM2INT(rencoding));
641
+ }
642
+ }
643
+
644
+ Data_Get_Struct(self, xmlDoc, xdoc);
645
+ xmlDocDumpFormatMemoryEnc(xdoc, &buffer, &length, xencoding, indent);
646
+
647
+ result = rb_str_new((const char*) buffer, length);
648
+ xmlFree(buffer);
649
+ return result;
650
+ }
651
+
652
+ /*
653
+ * call-seq:
654
+ * document.url -> "url"
655
+ *
656
+ * Obtain this document's source URL, if any.
657
+ */
658
+ static VALUE rxml_document_url_get(VALUE self)
659
+ {
660
+ xmlDocPtr xdoc;
661
+
662
+ Data_Get_Struct(self, xmlDoc, xdoc);
663
+ if (xdoc->URL == NULL)
664
+ return (Qnil);
665
+ else
666
+ return (rb_str_new2((const char*) xdoc->URL));
667
+ }
668
+
669
+ /*
670
+ * call-seq:
671
+ * document.version -> "version"
672
+ *
673
+ * Obtain the XML version specified by this document.
674
+ */
675
+ static VALUE rxml_document_version_get(VALUE self)
676
+ {
677
+ xmlDocPtr xdoc;
678
+
679
+ Data_Get_Struct(self, xmlDoc, xdoc);
680
+ if (xdoc->version == NULL)
681
+ return (Qnil);
682
+ else
683
+ return (rb_str_new2((const char*) xdoc->version));
684
+ }
685
+
686
+ /*
687
+ * call-seq:
688
+ * document.xhtml? -> (true|false)
689
+ *
690
+ * Determine whether this is an XHTML document.
691
+ */
692
+ static VALUE rxml_document_xhtml_q(VALUE self)
693
+ {
694
+ xmlDocPtr xdoc;
695
+ xmlDtdPtr xdtd;
696
+ Data_Get_Struct(self, xmlDoc, xdoc);
697
+ xdtd = xmlGetIntSubset(xdoc);
698
+ if (xdtd != NULL && xmlIsXHTML(xdtd->SystemID, xdtd->ExternalID) > 0)
699
+ return (Qtrue);
700
+ else
701
+ return (Qfalse);
702
+ }
703
+
704
+ /*
705
+ * call-seq:
706
+ * document.xinclude -> num
707
+ *
708
+ * Process xinclude directives in this document.
709
+ */
710
+ static VALUE rxml_document_xinclude(VALUE self)
711
+ {
712
+ #ifdef LIBXML_XINCLUDE_ENABLED
713
+ xmlDocPtr xdoc;
714
+
715
+ int ret;
716
+
717
+ Data_Get_Struct(self, xmlDoc, xdoc);
718
+ ret = xmlXIncludeProcess(xdoc);
719
+ if (ret >= 0)
720
+ {
721
+ return(INT2NUM(ret));
722
+ }
723
+ else
724
+ {
725
+ rxml_raise(&xmlLastError);
726
+ return Qnil;
727
+ }
728
+ #else
729
+ rb_warn(
730
+ "libxml was compiled without XInclude support. Please recompile libxml and ruby-libxml");
731
+ return (Qfalse);
732
+ #endif
733
+ }
734
+
735
+ void LibXML_validity_error(void * ctxt, const char * msg, va_list ap)
736
+ {
737
+ if (rb_block_given_p())
738
+ {
739
+ char buff[1024];
740
+ snprintf(buff, 1024, msg, ap);
741
+ rb_yield(rb_ary_new3(2, rb_str_new2(buff), Qtrue));
742
+ }
743
+ else
744
+ {
745
+ fprintf(stderr, "error -- found validity error: ");
746
+ fprintf(stderr, msg, ap);
747
+ }
748
+ }
749
+
750
+ /*
751
+ * call-seq:
752
+ * document.order_elements!
753
+ *
754
+ * Call this routine to speed up XPath computation on static documents.
755
+ * This stamps all the element nodes with the document order.
756
+ */
757
+ static VALUE rxml_document_order_elements(VALUE self)
758
+ {
759
+ xmlDocPtr xdoc;
760
+
761
+ Data_Get_Struct(self, xmlDoc, xdoc);
762
+ return LONG2FIX(xmlXPathOrderDocElems(xdoc));
763
+ }
764
+
765
+ /*
766
+ * call-seq:
767
+ * document.validate_schema(schema) -> (true|false)
768
+ *
769
+ * Validate this document against the specified XML::Schema.
770
+ *
771
+ * If a block is provided it is used as an error handler for validaten errors.
772
+ * The block is called with two argument, the message and a flag indication
773
+ * if the message is an error (true) or a warning (false).
774
+ */
775
+ static VALUE rxml_document_validate_schema(VALUE self, VALUE schema)
776
+ {
777
+ xmlSchemaValidCtxtPtr vptr;
778
+ xmlDocPtr xdoc;
779
+ xmlSchemaPtr xschema;
780
+ int is_invalid;
781
+
782
+ Data_Get_Struct(self, xmlDoc, xdoc);
783
+ Data_Get_Struct(schema, xmlSchema, xschema);
784
+
785
+ vptr = xmlSchemaNewValidCtxt(xschema);
786
+
787
+ xmlSchemaSetValidErrors(vptr,
788
+ (xmlSchemaValidityErrorFunc) LibXML_validity_error,
789
+ (xmlSchemaValidityWarningFunc) LibXML_validity_warning, NULL);
790
+
791
+ is_invalid = xmlSchemaValidateDoc(vptr, xdoc);
792
+ xmlSchemaFreeValidCtxt(vptr);
793
+ if (is_invalid)
794
+ {
795
+ rxml_raise(&xmlLastError);
796
+ return Qfalse;
797
+ }
798
+ else
799
+ {
800
+ return Qtrue;
801
+ }
802
+ }
803
+
804
+ /*
805
+ * call-seq:
806
+ * document.validate_schema(relaxng) -> (true|false)
807
+ *
808
+ * Validate this document against the specified XML::RelaxNG.
809
+ *
810
+ * If a block is provided it is used as an error handler for validaten errors.
811
+ * The block is called with two argument, the message and a flag indication
812
+ * if the message is an error (true) or a warning (false).
813
+ */
814
+ static VALUE rxml_document_validate_relaxng(VALUE self, VALUE relaxng)
815
+ {
816
+ xmlRelaxNGValidCtxtPtr vptr;
817
+ xmlDocPtr xdoc;
818
+ xmlRelaxNGPtr xrelaxng;
819
+ int is_invalid;
820
+
821
+ Data_Get_Struct(self, xmlDoc, xdoc);
822
+ Data_Get_Struct(relaxng, xmlRelaxNG, xrelaxng);
823
+
824
+ vptr = xmlRelaxNGNewValidCtxt(xrelaxng);
825
+
826
+ xmlRelaxNGSetValidErrors(vptr,
827
+ (xmlRelaxNGValidityErrorFunc) LibXML_validity_error,
828
+ (xmlRelaxNGValidityWarningFunc) LibXML_validity_warning, NULL);
829
+
830
+ is_invalid = xmlRelaxNGValidateDoc(vptr, xdoc);
831
+ xmlRelaxNGFreeValidCtxt(vptr);
832
+ if (is_invalid)
833
+ {
834
+ rxml_raise(&xmlLastError);
835
+ return Qfalse;
836
+ }
837
+ else
838
+ {
839
+ return Qtrue;
840
+ }
841
+ }
842
+
843
+ /*
844
+ * call-seq:
845
+ * document.validate(dtd) -> (true|false)
846
+ *
847
+ * Validate this document against the specified XML::DTD.
848
+ */
849
+ static VALUE rxml_document_validate_dtd(VALUE self, VALUE dtd)
850
+ {
851
+ VALUE error = Qnil;
852
+ xmlValidCtxt ctxt;
853
+ xmlDocPtr xdoc;
854
+ xmlDtdPtr xdtd;
855
+
856
+ Data_Get_Struct(self, xmlDoc, xdoc);
857
+ Data_Get_Struct(dtd, xmlDtd, xdtd);
858
+
859
+ ctxt.userData = &error;
860
+ ctxt.error = (xmlValidityErrorFunc) LibXML_validity_error;
861
+ ctxt.warning = (xmlValidityWarningFunc) LibXML_validity_warning;
862
+
863
+ ctxt.nodeNr = 0;
864
+ ctxt.nodeTab = NULL;
865
+ ctxt.vstateNr = 0;
866
+ ctxt.vstateTab = NULL;
867
+
868
+ if (xmlValidateDtd(&ctxt, xdoc, xdtd))
869
+ {
870
+ return (Qtrue);
871
+ }
872
+ else
873
+ {
874
+ rxml_raise(&xmlLastError);
875
+ return Qfalse;
876
+ }
877
+ }
878
+
879
+ void rxml_init_document(void)
880
+ {
881
+ cXMLDocument = rb_define_class_under(mXML, "Document", rb_cObject);
882
+ rb_define_alloc_func(cXMLDocument, rxml_document_alloc);
883
+
884
+ rb_define_method(cXMLDocument, "initialize", rxml_document_initialize, -1);
885
+ rb_define_method(cXMLDocument, "child", rxml_document_child_get, 0);
886
+ rb_define_method(cXMLDocument, "child?", rxml_document_child_q, 0);
887
+ rb_define_method(cXMLDocument, "compression", rxml_document_compression_get, 0);
888
+ rb_define_method(cXMLDocument, "compression=", rxml_document_compression_set, 1);
889
+ rb_define_method(cXMLDocument, "compression?", rxml_document_compression_q, 0);
890
+ rb_define_method(cXMLDocument, "debug", rxml_document_debug, 0);
891
+ rb_define_method(cXMLDocument, "encoding", rxml_document_encoding_get, 0);
892
+ rb_define_method(cXMLDocument, "encoding=", rxml_document_encoding_set, 1);
893
+ rb_define_method(cXMLDocument, "last", rxml_document_last_get, 0);
894
+ rb_define_method(cXMLDocument, "last?", rxml_document_last_q, 0);
895
+ rb_define_method(cXMLDocument, "next", rxml_document_next_get, 0);
896
+ rb_define_method(cXMLDocument, "next?", rxml_document_next_q, 0);
897
+ rb_define_method(cXMLDocument, "node_type", rxml_document_node_type, 0);
898
+ rb_define_method(cXMLDocument, "order_elements!", rxml_document_order_elements, 0);
899
+ rb_define_method(cXMLDocument, "parent", rxml_document_parent_get, 0);
900
+ rb_define_method(cXMLDocument, "parent?", rxml_document_parent_q, 0);
901
+ rb_define_method(cXMLDocument, "prev", rxml_document_prev_get, 0);
902
+ rb_define_method(cXMLDocument, "prev?", rxml_document_prev_q, 0);
903
+ rb_define_method(cXMLDocument, "root", rxml_document_root_get, 0);
904
+ rb_define_method(cXMLDocument, "root=", rxml_document_root_set, 1);
905
+ rb_define_method(cXMLDocument, "save", rxml_document_save, -1);
906
+ rb_define_method(cXMLDocument, "standalone?", rxml_document_standalone_q, 0);
907
+ rb_define_method(cXMLDocument, "to_s", rxml_document_to_s, -1);
908
+ rb_define_method(cXMLDocument, "url", rxml_document_url_get, 0);
909
+ rb_define_method(cXMLDocument, "version", rxml_document_version_get, 0);
910
+ rb_define_method(cXMLDocument, "xhtml?", rxml_document_xhtml_q, 0);
911
+ rb_define_method(cXMLDocument, "xinclude", rxml_document_xinclude, 0);
912
+ rb_define_method(cXMLDocument, "validate", rxml_document_validate_dtd, 1);
913
+ rb_define_method(cXMLDocument, "validate_schema", rxml_document_validate_schema, 1);
914
+ rb_define_method(cXMLDocument, "validate_relaxng", rxml_document_validate_relaxng, 1);
915
+ }