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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. data/CHANGES +53 -0
  2. data/Rakefile +1 -0
  3. data/ext/libxml/build.log +4 -0
  4. data/ext/libxml/cbg.c +86 -86
  5. data/ext/libxml/libxml.c +878 -876
  6. data/ext/libxml/ruby_libxml.h +8 -4
  7. data/ext/libxml/ruby_xml_attr.c +36 -168
  8. data/ext/libxml/ruby_xml_attr.h +2 -4
  9. data/ext/libxml/ruby_xml_attr_decl.c +177 -0
  10. data/ext/libxml/ruby_xml_attr_decl.h +13 -0
  11. data/ext/libxml/ruby_xml_attributes.c +29 -20
  12. data/ext/libxml/ruby_xml_document.c +895 -898
  13. data/ext/libxml/ruby_xml_dtd.c +18 -1
  14. data/ext/libxml/ruby_xml_dtd.h +1 -0
  15. data/ext/libxml/ruby_xml_encoding.c +116 -0
  16. data/ext/libxml/ruby_xml_encoding.h +12 -0
  17. data/ext/libxml/ruby_xml_error.c +8 -2
  18. data/ext/libxml/ruby_xml_html_parser.c +53 -74
  19. data/ext/libxml/ruby_xml_html_parser.h +2 -3
  20. data/ext/libxml/ruby_xml_html_parser_context.c +145 -0
  21. data/ext/libxml/ruby_xml_html_parser_context.h +12 -0
  22. data/ext/libxml/ruby_xml_html_parser_options.c +48 -0
  23. data/ext/libxml/ruby_xml_html_parser_options.h +12 -0
  24. data/ext/libxml/ruby_xml_input_cbg.c +1 -1
  25. data/ext/libxml/ruby_xml_io.c +30 -0
  26. data/ext/libxml/ruby_xml_io.h +9 -0
  27. data/ext/libxml/ruby_xml_namespace.c +34 -16
  28. data/ext/libxml/ruby_xml_namespace.h +2 -2
  29. data/ext/libxml/ruby_xml_namespaces.c +6 -6
  30. data/ext/libxml/ruby_xml_node.c +1367 -1324
  31. data/ext/libxml/ruby_xml_node.h +2 -2
  32. data/ext/libxml/ruby_xml_parser.c +26 -78
  33. data/ext/libxml/ruby_xml_parser.h +1 -1
  34. data/ext/libxml/ruby_xml_parser_context.c +284 -13
  35. data/ext/libxml/ruby_xml_parser_context.h +1 -2
  36. data/ext/libxml/ruby_xml_parser_options.c +75 -0
  37. data/ext/libxml/ruby_xml_parser_options.h +14 -0
  38. data/ext/libxml/ruby_xml_reader.c +277 -183
  39. data/ext/libxml/ruby_xml_sax_parser.c +60 -57
  40. data/ext/libxml/ruby_xml_xpath_context.c +43 -8
  41. data/ext/libxml/ruby_xml_xpath_expression.c +6 -0
  42. data/ext/libxml/ruby_xml_xpath_object.c +107 -95
  43. data/ext/libxml/ruby_xml_xpath_object.h +9 -1
  44. data/ext/libxml/ruby_xml_xpointer.c +107 -107
  45. data/ext/libxml/version.h +2 -2
  46. data/ext/mingw/libxml_ruby.dll.a +0 -0
  47. data/ext/mingw/libxml_ruby.so +0 -0
  48. data/ext/vc/libxml_ruby.vcproj +43 -3
  49. data/lib/libxml.rb +2 -3
  50. data/lib/libxml/attr.rb +71 -2
  51. data/lib/libxml/attr_decl.rb +81 -0
  52. data/lib/libxml/document.rb +78 -14
  53. data/lib/libxml/html_parser.rb +75 -42
  54. data/lib/libxml/node.rb +11 -0
  55. data/lib/libxml/parser.rb +106 -62
  56. data/lib/libxml/reader.rb +12 -0
  57. data/lib/libxml/sax_parser.rb +42 -52
  58. data/lib/libxml/xpath_object.rb +15 -0
  59. data/test/model/atom.xml +12 -12
  60. data/test/model/bands.xml +4 -4
  61. data/test/model/books.xml +146 -147
  62. data/test/model/merge_bug_data.xml +1 -1
  63. data/test/model/rubynet.xml +1 -0
  64. data/test/model/shiporder.rng +1 -1
  65. data/test/model/shiporder.xml +22 -22
  66. data/test/model/shiporder.xsd +30 -30
  67. data/test/model/xinclude.xml +1 -1
  68. data/test/{tc_node_attr.rb → tc_attr.rb} +1 -1
  69. data/test/tc_attr_decl.rb +131 -0
  70. data/test/tc_deprecated_require.rb +1 -3
  71. data/test/tc_document.rb +13 -3
  72. data/test/tc_document_write.rb +5 -5
  73. data/test/tc_dtd.rb +13 -5
  74. data/test/tc_html_parser.rb +14 -26
  75. data/test/tc_node_cdata.rb +1 -3
  76. data/test/tc_node_comment.rb +2 -4
  77. data/test/tc_node_edit.rb +2 -3
  78. data/test/tc_node_text.rb +35 -1
  79. data/test/tc_node_write.rb +3 -3
  80. data/test/tc_node_xlink.rb +2 -4
  81. data/test/tc_parser.rb +163 -70
  82. data/test/tc_parser_context.rb +103 -42
  83. data/test/tc_reader.rb +173 -45
  84. data/test/tc_relaxng.rb +2 -2
  85. data/test/tc_sax_parser.rb +48 -52
  86. data/test/tc_schema.rb +2 -2
  87. data/test/tc_xpath.rb +37 -6
  88. data/test/tc_xpath_context.rb +7 -1
  89. data/test/tc_xpath_expression.rb +1 -3
  90. data/test/tc_xpointer.rb +1 -3
  91. data/test/test_suite.rb +2 -3
  92. metadata +20 -13
  93. data/ext/libxml/ruby_xml_input.c +0 -329
  94. data/ext/libxml/ruby_xml_input.h +0 -20
  95. data/lib/libxml/parser_context.rb +0 -17
  96. data/lib/libxml/parser_options.rb +0 -25
  97. data/test/model/simple.xml +0 -7
  98. data/test/tc_input.rb +0 -13
  99. data/test/tc_well_formed.rb +0 -11
@@ -0,0 +1,13 @@
1
+ /* $Id: ruby_xml_attr.h 666 2008-12-07 00:16:50Z cfis $ */
2
+
3
+ /* Please see the LICENSE file for copyright and distribution information */
4
+
5
+ #ifndef __RXML_ATTR_DECL__
6
+ #define __RXML_ATTR_DECL__
7
+
8
+ extern VALUE cXMLAttrDecl;
9
+
10
+ void ruby_init_xml_attr_decl(void);
11
+ VALUE rxml_attr_decl_wrap(xmlAttributePtr xattribute);
12
+ VALUE rxml_attr_decl_value_get(VALUE self);
13
+ #endif
@@ -59,14 +59,17 @@ VALUE rxml_attributes_node_get(VALUE self)
59
59
  {
60
60
  xmlNodePtr xnode;
61
61
  Data_Get_Struct(self, xmlNode, xnode);
62
- return (rxml_node_wrap(cXMLNode, xnode));
62
+ return rxml_node_wrap(xnode);
63
63
  }
64
64
 
65
65
  /*
66
66
  * call-seq:
67
- * attributes.get_attribute("name") -> XML::Attr
67
+ * attributes.get_attribute("name") -> (XML::Attr | XML::AtrrDecl)
68
68
  *
69
- * Returns the specified attribute.
69
+ * Returns the specified attribute. If the attribute does not
70
+ * exist but the document has an associated DTD that defines
71
+ * a default value for the attribute, then a XML::AttrDecl is
72
+ * returned.
70
73
  *
71
74
  * name: The name of the attribute, not including a namespace.
72
75
  *
@@ -83,17 +86,22 @@ static VALUE rxml_attributes_get_attribute(VALUE self, VALUE name)
83
86
 
84
87
  xattr = xmlHasProp(xnode, (xmlChar*) StringValuePtr(name));
85
88
 
86
- if (xattr)
87
- return (rxml_attr_wrap(xattr));
89
+ if (!xattr)
90
+ return Qnil;
91
+ else if (xattr->type == XML_ATTRIBUTE_DECL)
92
+ return rxml_attr_decl_wrap((xmlAttributePtr)xattr);
88
93
  else
89
- return (Qnil);
94
+ return rxml_attr_wrap(xattr);
90
95
  }
91
96
 
92
97
  /*
93
98
  * call-seq:
94
- * attributes.get_attribute_ns("namespace", "name") -> XML::Attr
99
+ * attributes.get_attribute_ns("namespace", "name") -> (XML::Attr | XML::AtrrDecl)
95
100
  *
96
- * Returns the specified attribute.
101
+ * Returns the specified attribute. If the attribute does not
102
+ * exist but the document has an associated DTD that defines
103
+ * a default value for the attribute, then a XML::AttrDecl is
104
+ * returned.
97
105
  *
98
106
  * namespace: The URI of the attribute's namespace.
99
107
  * name: The name of the attribute, not including a namespace.
@@ -111,12 +119,14 @@ static VALUE rxml_attributes_get_attribute_ns(VALUE self, VALUE namespace,
111
119
  Data_Get_Struct(self, xmlNode, xnode);
112
120
 
113
121
  xattr = xmlHasNsProp(xnode, (xmlChar*) StringValuePtr(name),
114
- (xmlChar*) StringValuePtr(namespace));
122
+ (xmlChar*) StringValuePtr(namespace));
115
123
 
116
- if (xattr)
117
- return (rxml_attr_wrap(xattr));
124
+ if (!xattr)
125
+ return Qnil;
126
+ else if (xattr->type == XML_ATTRIBUTE_DECL)
127
+ return rxml_attr_decl_wrap((xmlAttributePtr)xattr);
118
128
  else
119
- return (Qnil);
129
+ return rxml_attr_wrap(xattr);
120
130
  }
121
131
 
122
132
  /*
@@ -133,8 +143,9 @@ static VALUE rxml_attributes_get_attribute_ns(VALUE self, VALUE namespace,
133
143
  VALUE rxml_attributes_attribute_get(VALUE self, VALUE name)
134
144
  {
135
145
  VALUE xattr = rxml_attributes_get_attribute(self, name);
146
+
136
147
  if (NIL_P(xattr))
137
- return(Qnil);
148
+ return Qnil;
138
149
  else
139
150
  return rxml_attr_value_get(xattr);
140
151
  }
@@ -218,7 +229,7 @@ static VALUE rxml_attributes_length(VALUE self)
218
229
  length++;
219
230
  xattr = xattr->next;
220
231
  }
221
-
232
+
222
233
  return INT2NUM(length);
223
234
  }
224
235
 
@@ -241,10 +252,10 @@ static VALUE rxml_attributes_first(VALUE self)
241
252
 
242
253
  if (xattr)
243
254
  {
244
- return (rxml_attr_wrap(xattr));
255
+ return rxml_attr_wrap(xattr);
245
256
  }
246
257
  }
247
- return (Qnil);
258
+ return Qnil;
248
259
  }
249
260
 
250
261
  // Rdoc needs to know
@@ -258,10 +269,8 @@ void ruby_init_xml_attributes(void)
258
269
  cXMLAttributes = rb_define_class_under(mXML, "Attributes", rb_cObject);
259
270
  rb_include_module(cXMLAttributes, rb_mEnumerable);
260
271
  rb_define_method(cXMLAttributes, "node", rxml_attributes_node_get, 0);
261
- rb_define_method(cXMLAttributes, "get_attribute",
262
- rxml_attributes_get_attribute, 1);
263
- rb_define_method(cXMLAttributes, "get_attribute_ns",
264
- rxml_attributes_get_attribute_ns, 2);
272
+ rb_define_method(cXMLAttributes, "get_attribute", rxml_attributes_get_attribute, 1);
273
+ rb_define_method(cXMLAttributes, "get_attribute_ns", rxml_attributes_get_attribute_ns, 2);
265
274
  rb_define_method(cXMLAttributes, "[]", rxml_attributes_attribute_get, 1);
266
275
  rb_define_method(cXMLAttributes, "[]=", rxml_attributes_attribute_set, 2);
267
276
  rb_define_method(cXMLAttributes, "each", rxml_attributes_each, 0);
@@ -1,898 +1,895 @@
1
- /* $Id: ruby_xml_document.c 688 2008-12-13 01:23:01Z 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('output.xml', format)
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
- * format = true
53
- * doc.save('output.xml', format)
54
- */
55
-
56
- #include <stdarg.h>
57
- #include <st.h>
58
- #include "ruby_libxml.h"
59
- #include "ruby_xml_document.h"
60
-
61
- VALUE cXMLDocument;
62
-
63
- static void LibXML_validity_warning(void * ctxt, const char * msg, va_list ap)
64
- {
65
- if (rb_block_given_p())
66
- {
67
- char buff[1024];
68
- snprintf(buff, 1024, msg, ap);
69
- rb_yield(rb_ary_new3(2, rb_str_new2(buff), Qfalse));
70
- }
71
- else
72
- {
73
- fprintf(stderr, "warning -- found validity error: ");
74
- fprintf(stderr, msg, ap);
75
- }
76
- }
77
-
78
- void rxml_document_free(xmlDocPtr xdoc)
79
- {
80
- xdoc->_private = NULL;
81
- xmlFreeDoc(xdoc);
82
- }
83
-
84
- void rxml_document_mark(xmlDocPtr xdoc)
85
- {
86
- rb_gc_mark(LIBXML_STATE);
87
- }
88
-
89
- VALUE rxml_document_wrap(xmlDocPtr xdoc)
90
- {
91
- VALUE result;
92
-
93
- // This node is already wrapped
94
- if (xdoc->_private != NULL)
95
- {
96
- result = (VALUE) xdoc->_private;
97
- }
98
- else
99
- {
100
- result = Data_Wrap_Struct(cXMLDocument, rxml_document_mark,
101
- rxml_document_free, xdoc);
102
- xdoc->_private = (void*) result;
103
- }
104
-
105
- return result;
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(cXMLNode, 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 -> "encoding"
293
- *
294
- * Obtain the encoding specified by this document.
295
- */
296
- static VALUE rxml_document_encoding_get(VALUE self)
297
- {
298
- xmlDocPtr xdoc;
299
-
300
- Data_Get_Struct(self, xmlDoc, xdoc);
301
- if (xdoc->encoding == NULL)
302
- return (Qnil);
303
- else
304
- return (rb_str_new2((const char*) xdoc->encoding));
305
- }
306
-
307
- /*
308
- * call-seq:
309
- * document.encoding = "encoding"
310
- *
311
- * Set the encoding for this document.
312
- */
313
- static VALUE rxml_document_encoding_set(VALUE self, VALUE encoding)
314
- {
315
- xmlDocPtr xdoc;
316
-
317
- Check_Type(encoding, T_STRING);
318
- Data_Get_Struct(self, xmlDoc, xdoc);
319
- xdoc->encoding = xmlStrdup((xmlChar *)StringValuePtr(encoding));
320
- return (rxml_document_encoding_get(self));
321
- }
322
-
323
- /*
324
- * call-seq:
325
- * document.last -> node
326
- *
327
- * Obtain the last node.
328
- */
329
- static VALUE rxml_document_last_get(VALUE self)
330
- {
331
- xmlDocPtr xdoc;
332
-
333
- Data_Get_Struct(self, xmlDoc, xdoc);
334
-
335
- if (xdoc->last == NULL)
336
- return (Qnil);
337
-
338
- return rxml_node_wrap(cXMLNode, xdoc->last);
339
- }
340
-
341
- /*
342
- * call-seq:
343
- * document.last? -> (true|false)
344
- *
345
- * Determine whether there is a last node.
346
- */
347
- static VALUE rxml_document_last_q(VALUE self)
348
- {
349
- xmlDocPtr xdoc;
350
-
351
- Data_Get_Struct(self, xmlDoc, xdoc);
352
-
353
- if (xdoc->last == NULL)
354
- return (Qfalse);
355
- else
356
- return (Qtrue);
357
- }
358
-
359
- /*
360
- * call-seq:
361
- * document.next -> node
362
- *
363
- * Obtain the next node.
364
- */
365
- static VALUE rxml_document_next_get(VALUE self)
366
- {
367
- xmlDocPtr xdoc;
368
-
369
- Data_Get_Struct(self, xmlDoc, xdoc);
370
-
371
- if (xdoc->next == NULL)
372
- return (Qnil);
373
-
374
- return rxml_node_wrap(cXMLNode, xdoc->next);
375
- }
376
-
377
- /*
378
- * call-seq:
379
- * document.next? -> (true|false)
380
- *
381
- * Determine whether there is a next node.
382
- */
383
- static VALUE rxml_document_next_q(VALUE self)
384
- {
385
- xmlDocPtr xdoc;
386
-
387
- Data_Get_Struct(self, xmlDoc, xdoc);
388
-
389
- if (xdoc->next == NULL)
390
- return (Qfalse);
391
- else
392
- return (Qtrue);
393
- }
394
-
395
- /*
396
- * call-seq:
397
- * document.parent -> node
398
- *
399
- * Obtain the parent node.
400
- */
401
- static VALUE rxml_document_parent_get(VALUE self)
402
- {
403
- xmlDocPtr xdoc;
404
-
405
- Data_Get_Struct(self, xmlDoc, xdoc);
406
-
407
- if (xdoc->parent == NULL)
408
- return (Qnil);
409
-
410
- return rxml_node_wrap(cXMLNode, xdoc->parent);
411
- }
412
-
413
- /*
414
- * call-seq:
415
- * document.parent? -> (true|false)
416
- *
417
- * Determine whether there is a parent node.
418
- */
419
- static VALUE rxml_document_parent_q(VALUE self)
420
- {
421
- xmlDocPtr xdoc;
422
-
423
- Data_Get_Struct(self, xmlDoc, xdoc);
424
-
425
- if (xdoc->parent == NULL)
426
- return (Qfalse);
427
- else
428
- return (Qtrue);
429
- }
430
-
431
- /*
432
- * call-seq:
433
- * document.prev -> node
434
- *
435
- * Obtain the previous node.
436
- */
437
- static VALUE rxml_document_prev_get(VALUE self)
438
- {
439
- xmlDocPtr xdoc;
440
-
441
- Data_Get_Struct(self, xmlDoc, xdoc);
442
-
443
- if (xdoc->prev == NULL)
444
- return (Qnil);
445
-
446
- return rxml_node_wrap(cXMLNode, xdoc->prev);
447
- }
448
-
449
- /*
450
- * call-seq:
451
- * document.prev? -> (true|false)
452
- *
453
- * Determine whether there is a previous node.
454
- */
455
- static VALUE rxml_document_prev_q(VALUE self)
456
- {
457
- xmlDocPtr xdoc;
458
-
459
- Data_Get_Struct(self, xmlDoc, xdoc);
460
-
461
- if (xdoc->prev == NULL)
462
- return (Qfalse);
463
- else
464
- return (Qtrue);
465
- }
466
-
467
- /*
468
- * call-seq:
469
- * document.root -> node
470
- *
471
- * Obtain the root node.
472
- */
473
- static VALUE rxml_document_root_get(VALUE self)
474
- {
475
- xmlDocPtr xdoc;
476
-
477
- xmlNodePtr root;
478
-
479
- Data_Get_Struct(self, xmlDoc, xdoc);
480
- root = xmlDocGetRootElement(xdoc);
481
-
482
- if (root == NULL)
483
- return (Qnil);
484
-
485
- return rxml_node_wrap(cXMLNode, root);
486
- }
487
-
488
- /*
489
- * call-seq:
490
- * document.root = node
491
- *
492
- * Set the root node.
493
- */
494
- static VALUE rxml_document_root_set(VALUE self, VALUE node)
495
- {
496
- xmlDocPtr xdoc;
497
- xmlNodePtr xroot, xnode;
498
-
499
- if (rb_obj_is_kind_of(node, cXMLNode) == Qfalse)
500
- rb_raise(rb_eTypeError, "must pass an XML::Node type object");
501
-
502
- Data_Get_Struct(self, xmlDoc, xdoc);
503
- Data_Get_Struct(node, xmlNode, xnode);
504
- xroot = xmlDocSetRootElement(xdoc, xnode);
505
- if (xroot == NULL)
506
- return (Qnil);
507
-
508
- return rxml_node_wrap(cXMLNode, xroot);
509
- }
510
-
511
- /*
512
- * call-seq:
513
- * document.save(filename) -> int
514
- * document.save(filename, :indent => true, :encoding => 'UTF-8') -> int
515
- *
516
- * Saves a document to a file. You may provide an optional hash table
517
- * to control how the string is generated. Valid options are:
518
- *
519
- * :indent - Specifies if the string should be indented. The default value
520
- * is true. Note that indentation is only added if both :indent is
521
- * true and XML.indent_tree_output is true. If :indent is set to false,
522
- * then both indentation and line feeds are removed from the result.
523
- *
524
- * :encoding - Specifies the output encoding of the string. It
525
- * defaults to the original encoding of the document (see
526
- * #encoding. To override the orginal encoding, use one of the
527
- * XML::Input encoding constants. */
528
- static VALUE rxml_document_save(int argc, VALUE *argv, VALUE self)
529
- {
530
- VALUE options = Qnil;
531
- VALUE filename = Qnil;
532
- xmlDocPtr xdoc;
533
- int indent = 1;
534
- const char *xfilename;
535
- const char *encoding;
536
- int length;
537
-
538
- rb_scan_args(argc, argv, "11", &filename, &options);
539
-
540
- Check_Type(filename, T_STRING);
541
- xfilename = StringValuePtr(filename);
542
-
543
- Data_Get_Struct(self, xmlDoc, xdoc);
544
- encoding = xdoc->encoding;
545
-
546
- if (!NIL_P(options))
547
- {
548
- VALUE rencoding, rindent;
549
- Check_Type(options, T_HASH);
550
- rencoding = rb_hash_aref(options, ID2SYM(rb_intern("encoding")));
551
- rindent = rb_hash_aref(options, ID2SYM(rb_intern("indent")));
552
-
553
- if (rindent == Qfalse)
554
- indent = 0;
555
-
556
- if (rencoding != Qnil)
557
- encoding = RSTRING_PTR(rxml_input_encoding_to_s(cXMLInput, rencoding));
558
- }
559
-
560
- length = xmlSaveFormatFileEnc(xfilename, xdoc, encoding, indent);
561
-
562
- if (length == -1)
563
- rxml_raise(&xmlLastError);
564
-
565
- return (INT2NUM(length));
566
- }
567
-
568
- /*
569
- * call-seq:
570
- * document.standalone? -> (true|false)
571
- *
572
- * Determine whether this is a standalone document.
573
- */
574
- static VALUE rxml_document_standalone_q(VALUE self)
575
- {
576
- xmlDocPtr xdoc;
577
-
578
- Data_Get_Struct(self, xmlDoc, xdoc);
579
- if (xdoc->standalone)
580
- return (Qtrue);
581
- else
582
- return (Qfalse);
583
- }
584
-
585
- /*
586
- * call-seq:
587
- * document.to_s -> "string"
588
- * document.to_s(:indent => true, :encoding => 'UTF-8') -> "string"
589
- *
590
- * Converts a document, and all of its children, to a string representation.
591
- * You may provide an optional hash table to control how the string is
592
- * generated. Valid options are:
593
- *
594
- * :indent - Specifies if the string should be indented. The default value
595
- * is true. Note that indentation is only added if both :indent is
596
- * true and XML.indent_tree_output is true. If :indent is set to false,
597
- * then both indentation and line feeds are removed from the result.
598
- *
599
- * :encoding - Specifies the output encoding of the string. It
600
- * defaults to XML::Input::UTF8. To change it, use one of the
601
- * XML::Input encoding constants. */
602
- static VALUE rxml_document_to_s(int argc, VALUE *argv, VALUE self)
603
- {
604
- VALUE result;
605
- VALUE options = Qnil;
606
- xmlDocPtr xdoc;
607
- int indent = 1;
608
- const char *encoding = "UTF-8";
609
- xmlChar *buffer;
610
- int length;
611
-
612
- rb_scan_args(argc, argv, "01", &options);
613
-
614
- if (!NIL_P(options))
615
- {
616
- VALUE rencoding, rindent;
617
- Check_Type(options, T_HASH);
618
- rencoding = rb_hash_aref(options, ID2SYM(rb_intern("encoding")));
619
- rindent = rb_hash_aref(options, ID2SYM(rb_intern("indent")));
620
-
621
- if (rindent == Qfalse)
622
- indent = 0;
623
-
624
- if (rencoding != Qnil)
625
- encoding = RSTRING_PTR(rxml_input_encoding_to_s(cXMLInput, rencoding));
626
- }
627
-
628
- Data_Get_Struct(self, xmlDoc, xdoc);
629
- xmlDocDumpFormatMemoryEnc(xdoc, &buffer, &length, encoding, indent);
630
-
631
- result = rb_str_new((const char*) buffer, length);
632
- xmlFree(buffer);
633
- return result;
634
- }
635
-
636
- /*
637
- * call-seq:
638
- * document.url -> "url"
639
- *
640
- * Obtain this document's source URL, if any.
641
- */
642
- static VALUE rxml_document_url_get(VALUE self)
643
- {
644
- xmlDocPtr xdoc;
645
-
646
- Data_Get_Struct(self, xmlDoc, xdoc);
647
- if (xdoc->URL == NULL)
648
- return (Qnil);
649
- else
650
- return (rb_str_new2((const char*) xdoc->URL));
651
- }
652
-
653
- /*
654
- * call-seq:
655
- * document.version -> "version"
656
- *
657
- * Obtain the XML version specified by this document.
658
- */
659
- static VALUE rxml_document_version_get(VALUE self)
660
- {
661
- xmlDocPtr xdoc;
662
-
663
- Data_Get_Struct(self, xmlDoc, xdoc);
664
- if (xdoc->version == NULL)
665
- return (Qnil);
666
- else
667
- return (rb_str_new2((const char*) xdoc->version));
668
- }
669
-
670
- /*
671
- * call-seq:
672
- * document.xinclude -> num
673
- *
674
- * Process xinclude directives in this document.
675
- */
676
- static VALUE rxml_document_xinclude(VALUE self)
677
- {
678
- #ifdef LIBXML_XINCLUDE_ENABLED
679
- xmlDocPtr xdoc;
680
-
681
- int ret;
682
-
683
- Data_Get_Struct(self, xmlDoc, xdoc);
684
- ret = xmlXIncludeProcess(xdoc);
685
- if (ret >= 0)
686
- {
687
- return(INT2NUM(ret));
688
- }
689
- else
690
- {
691
- rxml_raise(&xmlLastError);
692
- return Qnil;
693
- }
694
- #else
695
- rb_warn(
696
- "libxml was compiled without XInclude support. Please recompile libxml and ruby-libxml");
697
- return (Qfalse);
698
- #endif
699
- }
700
-
701
- void LibXML_validity_error(void * ctxt, const char * msg, va_list ap)
702
- {
703
- if (rb_block_given_p())
704
- {
705
- char buff[1024];
706
- snprintf(buff, 1024, msg, ap);
707
- rb_yield(rb_ary_new3(2, rb_str_new2(buff), Qtrue));
708
- }
709
- else
710
- {
711
- fprintf(stderr, "error -- found validity error: ");
712
- fprintf(stderr, msg, ap);
713
- }
714
- }
715
-
716
- /*
717
- * call-seq:
718
- * document.order_elements!
719
- *
720
- * Call this routine to speed up XPath computation on static documents.
721
- * This stamps all the element nodes with the document order.
722
- */
723
- static VALUE rxml_document_order_elements(VALUE self)
724
- {
725
- xmlDocPtr xdoc;
726
-
727
- Data_Get_Struct(self, xmlDoc, xdoc);
728
- return LONG2FIX(xmlXPathOrderDocElems(xdoc));
729
- }
730
-
731
- /*
732
- * call-seq:
733
- * document.validate_schema(schema) -> (true|false)
734
- *
735
- * Validate this document against the specified XML::Schema.
736
- *
737
- * If a block is provided it is used as an error handler for validaten errors.
738
- * The block is called with two argument, the message and a flag indication
739
- * if the message is an error (true) or a warning (false).
740
- */
741
- static VALUE rxml_document_validate_schema(VALUE self, VALUE schema)
742
- {
743
- xmlSchemaValidCtxtPtr vptr;
744
- xmlDocPtr xdoc;
745
- xmlSchemaPtr xschema;
746
- int is_invalid;
747
-
748
- Data_Get_Struct(self, xmlDoc, xdoc);
749
- Data_Get_Struct(schema, xmlSchema, xschema);
750
-
751
- vptr = xmlSchemaNewValidCtxt(xschema);
752
-
753
- xmlSchemaSetValidErrors(vptr,
754
- (xmlSchemaValidityErrorFunc) LibXML_validity_error,
755
- (xmlSchemaValidityWarningFunc) LibXML_validity_warning, NULL);
756
-
757
- is_invalid = xmlSchemaValidateDoc(vptr, xdoc);
758
- xmlSchemaFreeValidCtxt(vptr);
759
- if (is_invalid)
760
- {
761
- rxml_raise(&xmlLastError);
762
- return Qfalse;
763
- }
764
- else
765
- {
766
- return Qtrue;
767
- }
768
- }
769
-
770
- /*
771
- * call-seq:
772
- * document.validate_schema(relaxng) -> (true|false)
773
- *
774
- * Validate this document against the specified XML::RelaxNG.
775
- *
776
- * If a block is provided it is used as an error handler for validaten errors.
777
- * The block is called with two argument, the message and a flag indication
778
- * if the message is an error (true) or a warning (false).
779
- */
780
- static VALUE rxml_document_validate_relaxng(VALUE self, VALUE relaxng)
781
- {
782
- xmlRelaxNGValidCtxtPtr vptr;
783
- xmlDocPtr xdoc;
784
- xmlRelaxNGPtr xrelaxng;
785
- int is_invalid;
786
-
787
- Data_Get_Struct(self, xmlDoc, xdoc);
788
- Data_Get_Struct(relaxng, xmlRelaxNG, xrelaxng);
789
-
790
- vptr = xmlRelaxNGNewValidCtxt(xrelaxng);
791
-
792
- xmlRelaxNGSetValidErrors(vptr,
793
- (xmlRelaxNGValidityErrorFunc) LibXML_validity_error,
794
- (xmlRelaxNGValidityWarningFunc) LibXML_validity_warning, NULL);
795
-
796
- is_invalid = xmlRelaxNGValidateDoc(vptr, xdoc);
797
- xmlRelaxNGFreeValidCtxt(vptr);
798
- if (is_invalid)
799
- {
800
- rxml_raise(&xmlLastError);
801
- return Qfalse;
802
- }
803
- else
804
- {
805
- return Qtrue;
806
- }
807
- }
808
-
809
- /*
810
- * call-seq:
811
- * document.validate(dtd) -> (true|false)
812
- *
813
- * Validate this document against the specified XML::DTD.
814
- */
815
- static VALUE rxml_document_validate_dtd(VALUE self, VALUE dtd)
816
- {
817
- VALUE error = Qnil;
818
- xmlValidCtxt ctxt;
819
- xmlDocPtr xdoc;
820
- xmlDtdPtr xdtd;
821
-
822
- Data_Get_Struct(self, xmlDoc, xdoc);
823
- Data_Get_Struct(dtd, xmlDtd, xdtd);
824
-
825
- ctxt.userData = &error;
826
- ctxt.error = (xmlValidityErrorFunc) LibXML_validity_error;
827
- ctxt.warning = (xmlValidityWarningFunc) LibXML_validity_warning;
828
-
829
- ctxt.nodeNr = 0;
830
- ctxt.nodeTab = NULL;
831
- ctxt.vstateNr = 0;
832
- ctxt.vstateTab = NULL;
833
-
834
- if (xmlValidateDtd(&ctxt, xdoc, xdtd))
835
- {
836
- return (Qtrue);
837
- }
838
- else
839
- {
840
- rxml_raise(&xmlLastError);
841
- return Qfalse;
842
- }
843
- }
844
-
845
- /*
846
- * call-seq:
847
- * document.reader -> reader
848
- *
849
- * Create a XML::Reader from the document. This is a shortcut to
850
- * XML::Reader.walker().
851
- */
852
- static VALUE rxml_document_reader(VALUE self)
853
- {
854
- return rxml_reader_new_walker(cXMLReader, self);
855
- }
856
-
857
- // Rdoc needs to know
858
- #ifdef RDOC_NEVER_DEFINED
859
- mLibXML = rb_define_module("LibXML");
860
- mXML = rb_define_module_under(mLibXML, "XML");
861
- #endif
862
-
863
- void ruby_init_xml_document(void)
864
- {
865
- cXMLDocument = rb_define_class_under(mXML, "Document", rb_cObject);
866
- rb_define_alloc_func(cXMLDocument, rxml_document_alloc);
867
-
868
- rb_define_method(cXMLDocument, "initialize", rxml_document_initialize, -1);
869
- rb_define_method(cXMLDocument, "child", rxml_document_child_get, 0);
870
- rb_define_method(cXMLDocument, "child?", rxml_document_child_q, 0);
871
- rb_define_method(cXMLDocument, "compression", rxml_document_compression_get, 0);
872
- rb_define_method(cXMLDocument, "compression=", rxml_document_compression_set, 1);
873
- rb_define_method(cXMLDocument, "compression?", rxml_document_compression_q, 0);
874
- rb_define_method(cXMLDocument, "debug", rxml_document_debug, 0);
875
- rb_define_method(cXMLDocument, "encoding", rxml_document_encoding_get, 0);
876
- rb_define_method(cXMLDocument, "encoding=", rxml_document_encoding_set, 1);
877
- rb_define_method(cXMLDocument, "last", rxml_document_last_get, 0);
878
- rb_define_method(cXMLDocument, "last?", rxml_document_last_q, 0);
879
- rb_define_method(cXMLDocument, "next", rxml_document_next_get, 0);
880
- rb_define_method(cXMLDocument, "next?", rxml_document_next_q, 0);
881
- rb_define_method(cXMLDocument, "order_elements!", rxml_document_order_elements, 0);
882
- rb_define_method(cXMLDocument, "parent", rxml_document_parent_get, 0);
883
- rb_define_method(cXMLDocument, "parent?", rxml_document_parent_q, 0);
884
- rb_define_method(cXMLDocument, "prev", rxml_document_prev_get, 0);
885
- rb_define_method(cXMLDocument, "prev?", rxml_document_prev_q, 0);
886
- rb_define_method(cXMLDocument, "root", rxml_document_root_get, 0);
887
- rb_define_method(cXMLDocument, "root=", rxml_document_root_set, 1);
888
- rb_define_method(cXMLDocument, "save", rxml_document_save, -1);
889
- rb_define_method(cXMLDocument, "standalone?", rxml_document_standalone_q, 0);
890
- rb_define_method(cXMLDocument, "to_s", rxml_document_to_s, -1);
891
- rb_define_method(cXMLDocument, "url", rxml_document_url_get, 0);
892
- rb_define_method(cXMLDocument, "version", rxml_document_version_get, 0);
893
- rb_define_method(cXMLDocument, "xinclude", rxml_document_xinclude, 0);
894
- rb_define_method(cXMLDocument, "validate", rxml_document_validate_dtd, 1);
895
- rb_define_method(cXMLDocument, "validate_schema", rxml_document_validate_schema, 1);
896
- rb_define_method(cXMLDocument, "validate_relaxng", rxml_document_validate_relaxng, 1);
897
- rb_define_method(cXMLDocument, "reader", rxml_document_reader, 0);
898
- }
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
+ }