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 +8 -0
- data/ext/libxml/extconf.rb +0 -8
- data/ext/libxml/libxml.c +76 -76
- data/ext/libxml/ruby_libxml.h +93 -93
- data/ext/libxml/ruby_xml_document.c +915 -915
- data/ext/libxml/ruby_xml_dtd.c +257 -257
- data/ext/libxml/ruby_xml_html_parser_context.c +290 -175
- data/ext/libxml/ruby_xml_node.c +1428 -1428
- data/ext/libxml/ruby_xml_parser_context.c +952 -952
- data/ext/libxml/ruby_xml_reader.c +1002 -1002
- data/ext/libxml/ruby_xml_version.h +5 -5
- data/ext/libxml/ruby_xml_xpath_context.c +387 -387
- data/ext/mingw/libxml_ruby.dll.a +0 -0
- data/ext/mingw/libxml_ruby.so +0 -0
- metadata +2 -3
- data/test/model/definition.dtd +0 -8
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
|
|
data/ext/libxml/extconf.rb
CHANGED
@@ -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
|
+
}
|
data/ext/libxml/ruby_libxml.h
CHANGED
@@ -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
|
+
}
|