libxml-ruby 0.9.9-x86-mswin32-60 → 1.0.0-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.
data/CHANGES CHANGED
@@ -1,3 +1,9 @@
1
+ == 1.0.0 / 2009-03-05 Charlie Savage
2
+
3
+ * OS X (Charlie Savage). Update bindings to support the default installed
4
+ version of libxml2 (2.6.16) on OS X 10.5 and the latest version available
5
+ via MacPorts.
6
+
1
7
  == 0.9.9 / 2009-03-05 Charlie Savage
2
8
 
3
9
  * Ruby 1.9.1 support (Charlie Savage). libxml-ruby now compiles and runs on either
@@ -37,6 +43,8 @@
37
43
 
38
44
  * Bug fix - Fix output escaping on attributes nodes (Joe Khoobyar).
39
45
 
46
+ * Bug fix - Make sure IO objects are not garbage collected when used
47
+ as parser sources (Charlie Savage).
40
48
 
41
49
  == 0.9.8 / 2009-1-24 Charlie Savage
42
50
 
@@ -114,14 +114,6 @@ need libxml2.
114
114
  EOL
115
115
  end
116
116
 
117
- unless have_func('xmlDocFormatDump')
118
- crash('Your version of libxml2 is too old. Please upgrade.')
119
- end
120
-
121
- unless have_func('docbCreateFileParserCtxt')
122
- crash('Need docbCreateFileParserCtxt')
123
- end
124
-
125
117
  # For FreeBSD add /usr/local/include
126
118
  $INCFLAGS << " -I/usr/local/include"
127
119
 
data/ext/libxml/libxml.c CHANGED
@@ -1,76 +1,76 @@
1
- #include "ruby_libxml.h"
2
-
3
- #if RUBY_INTERN_H
4
- #include <ruby/util.h>
5
- #else
6
- #include <util.h>
7
- #endif
8
-
9
- VALUE mLibXML;
10
-
11
- static void rxml_init_memory(void)
12
- {
13
- xmlGcMemSetup(
14
- (xmlFreeFunc)ruby_xfree,
15
- (xmlMallocFunc)ruby_xmalloc,
16
- (xmlMallocFunc)ruby_xmalloc,
17
- (xmlReallocFunc)ruby_xrealloc,
18
- (xmlStrdupFunc)ruby_strdup
19
- );
20
- }
21
-
22
- #if defined(_WIN32)
23
- __declspec(dllexport)
24
- #endif
25
- void Init_libxml_ruby(void)
26
- {
27
- /* The libxml gem provides Ruby language bindings for GNOME's Libxml2
28
- * XML toolkit. To get started you may:
29
- *
30
- * require 'xml'
31
- * document = XML::Document.new
32
- *
33
- * However, when creating an application or library you plan to
34
- * redistribute, it is best to not add the LibXML module to the global
35
- * namespace, in which case you can either write your code like this:
36
- *
37
- * require 'libxml'
38
- * document = LibXML::XML::Document.new
39
- *
40
- * Refer to the README file to get started and the LICENSE file for
41
- * copyright and distribution information.
42
- */
43
- mLibXML = rb_define_module("LibXML");
44
-
45
- rxml_init_memory();
46
- rxml_init_xml();
47
- rxml_init_io();
48
- rxml_init_error();
49
- rxml_init_encoding();
50
- rxml_init_parser();
51
- rxml_init_parser_context();
52
- rxml_init_parser_options();
53
- rxml_init_node();
54
- rxml_init_attributes();
55
- rxml_init_attr();
56
- rxml_init_attr_decl();
57
- rxml_init_document();
58
- rxml_init_namespaces();
59
- rxml_init_namespace();
60
- rxml_init_sax_parser();
61
- rxml_init_sax2_handler();
62
- rxml_init_xinclude();
63
- rxml_init_xpath();
64
- rxml_init_xpath_object();
65
- rxml_init_xpath_context();
66
- rxml_init_xpath_expression();
67
- rxml_init_xpointer();
68
- rxml_init_html_parser();
69
- rxml_init_html_parser_options();
70
- rxml_init_html_parser_context();
71
- rxml_init_input_callbacks();
72
- rxml_init_dtd();
73
- rxml_init_schema();
74
- rxml_init_relaxng();
75
- rxml_init_reader();
76
- }
1
+ #include "ruby_libxml.h"
2
+
3
+ #if RUBY_INTERN_H
4
+ #include <ruby/util.h>
5
+ #else
6
+ #include <util.h>
7
+ #endif
8
+
9
+ VALUE mLibXML;
10
+
11
+ static void rxml_init_memory(void)
12
+ {
13
+ xmlGcMemSetup(
14
+ (xmlFreeFunc)ruby_xfree,
15
+ (xmlMallocFunc)ruby_xmalloc,
16
+ (xmlMallocFunc)ruby_xmalloc,
17
+ (xmlReallocFunc)ruby_xrealloc,
18
+ (xmlStrdupFunc)ruby_strdup
19
+ );
20
+ }
21
+
22
+ #if defined(_WIN32)
23
+ __declspec(dllexport)
24
+ #endif
25
+ void Init_libxml_ruby(void)
26
+ {
27
+ /* The libxml gem provides Ruby language bindings for GNOME's Libxml2
28
+ * XML toolkit. To get started you may:
29
+ *
30
+ * require 'xml'
31
+ * document = XML::Document.new
32
+ *
33
+ * However, when creating an application or library you plan to
34
+ * redistribute, it is best to not add the LibXML module to the global
35
+ * namespace, in which case you can either write your code like this:
36
+ *
37
+ * require 'libxml'
38
+ * document = LibXML::XML::Document.new
39
+ *
40
+ * Refer to the README file to get started and the LICENSE file for
41
+ * copyright and distribution information.
42
+ */
43
+ mLibXML = rb_define_module("LibXML");
44
+
45
+ rxml_init_memory();
46
+ rxml_init_xml();
47
+ rxml_init_io();
48
+ rxml_init_error();
49
+ rxml_init_encoding();
50
+ rxml_init_parser();
51
+ rxml_init_parser_context();
52
+ rxml_init_parser_options();
53
+ rxml_init_node();
54
+ rxml_init_attributes();
55
+ rxml_init_attr();
56
+ rxml_init_attr_decl();
57
+ rxml_init_document();
58
+ rxml_init_namespaces();
59
+ rxml_init_namespace();
60
+ rxml_init_sax_parser();
61
+ rxml_init_sax2_handler();
62
+ rxml_init_xinclude();
63
+ rxml_init_xpath();
64
+ rxml_init_xpath_object();
65
+ rxml_init_xpath_context();
66
+ rxml_init_xpath_expression();
67
+ rxml_init_xpointer();
68
+ rxml_init_html_parser();
69
+ rxml_init_html_parser_options();
70
+ rxml_init_html_parser_context();
71
+ rxml_init_input_callbacks();
72
+ rxml_init_dtd();
73
+ rxml_init_schema();
74
+ rxml_init_relaxng();
75
+ rxml_init_reader();
76
+ }
@@ -1,93 +1,93 @@
1
- /* Please see the LICENSE file for copyright and distribution information */
2
-
3
- #ifndef __RUBY_LIBXML_H__
4
- #define __RUBY_LIBXML_H__
5
-
6
- #include <ruby.h>
7
- #include <libxml/parser.h>
8
- #include <libxml/parserInternals.h>
9
- #include <libxml/debugXML.h>
10
- #include <libxml/xmlversion.h>
11
- #include <libxml/xmlmemory.h>
12
- #include <libxml/xpath.h>
13
- #include <libxml/valid.h>
14
- #include <libxml/catalog.h>
15
- #include <libxml/HTMLparser.h>
16
- #include <libxml/xmlreader.h>
17
-
18
- /* Needed for Ruby 1.8.5 */
19
- #ifndef RARRAY_LEN
20
- #define RARRAY_LEN(s) (RARRAY(s)->len)
21
- #endif
22
-
23
- /* Needed for Ruby 1.8.5 */
24
- #ifndef RARRAY_PTR
25
- #define RARRAY_PTR(s) (RARRAY(s)->ptr)
26
- #endif
27
-
28
- /* Needed for Ruby 1.8.5 */
29
- #ifndef RSTRING_LEN
30
- #define RSTRING_LEN(s) (RSTRING(s)->len)
31
- #endif
32
-
33
- /* Needed for Ruby 1.8.5 */
34
- #ifndef RSTRING_PTR
35
- #define RSTRING_PTR(s) (RSTRING(s)->ptr)
36
- #endif
37
-
38
- /* Needed prior to Ruby 1.9.1 */
39
- #ifndef RHASH_TBL
40
- #define RHASH_TBL(s) (RHASH(s)->tbl)
41
- #endif
42
-
43
- // not in Ruby 1.9
44
- #ifndef GetWriteFile
45
- #define GetWriteFile(fp) rb_io_stdio_file(fp)
46
- #define OpenFile rb_io_t
47
- #endif
48
-
49
- #ifdef LIBXML_DEBUG_ENABLED
50
- #include <libxml/xpathInternals.h>
51
- #endif
52
- #ifdef LIBXML_XINCLUDE_ENABLED
53
- #include <libxml/xinclude.h>
54
- #endif
55
- #ifdef LIBXML_XPTR_ENABLED
56
- #include <libxml/xpointer.h>
57
- #endif
58
-
59
- #include "ruby_xml_version.h"
60
- #include "ruby_xml.h"
61
- #include "ruby_xml_io.h"
62
- #include "ruby_xml_error.h"
63
- #include "ruby_xml_encoding.h"
64
- #include "ruby_xml_attributes.h"
65
- #include "ruby_xml_attr.h"
66
- #include "ruby_xml_attr_decl.h"
67
- #include "ruby_xml_document.h"
68
- #include "ruby_xml_node.h"
69
- #include "ruby_xml_namespace.h"
70
- #include "ruby_xml_namespaces.h"
71
- #include "ruby_xml_parser.h"
72
- #include "ruby_xml_parser_options.h"
73
- #include "ruby_xml_parser_context.h"
74
- #include "ruby_xml_html_parser.h"
75
- #include "ruby_xml_html_parser_options.h"
76
- #include "ruby_xml_html_parser_context.h"
77
- #include "ruby_xml_reader.h"
78
- #include "ruby_xml_sax2_handler.h"
79
- #include "ruby_xml_sax_parser.h"
80
- #include "ruby_xml_xinclude.h"
81
- #include "ruby_xml_xpath.h"
82
- #include "ruby_xml_xpath_expression.h"
83
- #include "ruby_xml_xpath_context.h"
84
- #include "ruby_xml_xpath_object.h"
85
- #include "ruby_xml_xpointer.h"
86
- #include "ruby_xml_input_cbg.h"
87
- #include "ruby_xml_dtd.h"
88
- #include "ruby_xml_schema.h"
89
- #include "ruby_xml_relaxng.h"
90
-
91
- extern VALUE mLibXML;
92
-
93
- #endif
1
+ /* Please see the LICENSE file for copyright and distribution information */
2
+
3
+ #ifndef __RUBY_LIBXML_H__
4
+ #define __RUBY_LIBXML_H__
5
+
6
+ #include <ruby.h>
7
+ #include <libxml/parser.h>
8
+ #include <libxml/parserInternals.h>
9
+ #include <libxml/debugXML.h>
10
+ #include <libxml/xmlversion.h>
11
+ #include <libxml/xmlmemory.h>
12
+ #include <libxml/xpath.h>
13
+ #include <libxml/valid.h>
14
+ #include <libxml/catalog.h>
15
+ #include <libxml/HTMLparser.h>
16
+ #include <libxml/xmlreader.h>
17
+
18
+ /* Needed for Ruby 1.8.5 */
19
+ #ifndef RARRAY_LEN
20
+ #define RARRAY_LEN(s) (RARRAY(s)->len)
21
+ #endif
22
+
23
+ /* Needed for Ruby 1.8.5 */
24
+ #ifndef RARRAY_PTR
25
+ #define RARRAY_PTR(s) (RARRAY(s)->ptr)
26
+ #endif
27
+
28
+ /* Needed for Ruby 1.8.5 */
29
+ #ifndef RSTRING_LEN
30
+ #define RSTRING_LEN(s) (RSTRING(s)->len)
31
+ #endif
32
+
33
+ /* Needed for Ruby 1.8.5 */
34
+ #ifndef RSTRING_PTR
35
+ #define RSTRING_PTR(s) (RSTRING(s)->ptr)
36
+ #endif
37
+
38
+ /* Needed prior to Ruby 1.9.1 */
39
+ #ifndef RHASH_TBL
40
+ #define RHASH_TBL(s) (RHASH(s)->tbl)
41
+ #endif
42
+
43
+ // not in Ruby 1.9
44
+ #ifndef GetWriteFile
45
+ #define GetWriteFile(fp) rb_io_stdio_file(fp)
46
+ #define OpenFile rb_io_t
47
+ #endif
48
+
49
+ #ifdef LIBXML_DEBUG_ENABLED
50
+ #include <libxml/xpathInternals.h>
51
+ #endif
52
+ #ifdef LIBXML_XINCLUDE_ENABLED
53
+ #include <libxml/xinclude.h>
54
+ #endif
55
+ #ifdef LIBXML_XPTR_ENABLED
56
+ #include <libxml/xpointer.h>
57
+ #endif
58
+
59
+ #include "ruby_xml_version.h"
60
+ #include "ruby_xml.h"
61
+ #include "ruby_xml_io.h"
62
+ #include "ruby_xml_error.h"
63
+ #include "ruby_xml_encoding.h"
64
+ #include "ruby_xml_attributes.h"
65
+ #include "ruby_xml_attr.h"
66
+ #include "ruby_xml_attr_decl.h"
67
+ #include "ruby_xml_document.h"
68
+ #include "ruby_xml_node.h"
69
+ #include "ruby_xml_namespace.h"
70
+ #include "ruby_xml_namespaces.h"
71
+ #include "ruby_xml_parser.h"
72
+ #include "ruby_xml_parser_options.h"
73
+ #include "ruby_xml_parser_context.h"
74
+ #include "ruby_xml_html_parser.h"
75
+ #include "ruby_xml_html_parser_options.h"
76
+ #include "ruby_xml_html_parser_context.h"
77
+ #include "ruby_xml_reader.h"
78
+ #include "ruby_xml_sax2_handler.h"
79
+ #include "ruby_xml_sax_parser.h"
80
+ #include "ruby_xml_xinclude.h"
81
+ #include "ruby_xml_xpath.h"
82
+ #include "ruby_xml_xpath_expression.h"
83
+ #include "ruby_xml_xpath_context.h"
84
+ #include "ruby_xml_xpath_object.h"
85
+ #include "ruby_xml_xpointer.h"
86
+ #include "ruby_xml_input_cbg.h"
87
+ #include "ruby_xml_dtd.h"
88
+ #include "ruby_xml_schema.h"
89
+ #include "ruby_xml_relaxng.h"
90
+
91
+ extern VALUE mLibXML;
92
+
93
+ #endif
@@ -1,915 +1,915 @@
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
- }
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
+ }