libxml-ruby 0.3.6
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/CHANGELOG +49 -0
- data/LICENSE +22 -0
- data/README +129 -0
- data/Rakefile +197 -0
- data/TODO +84 -0
- data/ext/xml/cbg.c +76 -0
- data/ext/xml/extconf.rb +95 -0
- data/ext/xml/libxml.c +86 -0
- data/ext/xml/libxml.h +79 -0
- data/ext/xml/ruby_xml_attr.c +372 -0
- data/ext/xml/ruby_xml_attr.h +21 -0
- data/ext/xml/ruby_xml_attribute.c +224 -0
- data/ext/xml/ruby_xml_attribute.h +21 -0
- data/ext/xml/ruby_xml_document.c +1159 -0
- data/ext/xml/ruby_xml_document.h +27 -0
- data/ext/xml/ruby_xml_dtd.c +168 -0
- data/ext/xml/ruby_xml_dtd.h +17 -0
- data/ext/xml/ruby_xml_input_cbg.c +167 -0
- data/ext/xml/ruby_xml_input_cbg.h +21 -0
- data/ext/xml/ruby_xml_node.c +2052 -0
- data/ext/xml/ruby_xml_node.h +28 -0
- data/ext/xml/ruby_xml_node_set.c +197 -0
- data/ext/xml/ruby_xml_node_set.h +26 -0
- data/ext/xml/ruby_xml_ns.c +153 -0
- data/ext/xml/ruby_xml_ns.h +21 -0
- data/ext/xml/ruby_xml_parser.c +1363 -0
- data/ext/xml/ruby_xml_parser.h +31 -0
- data/ext/xml/ruby_xml_parser_context.c +715 -0
- data/ext/xml/ruby_xml_parser_context.h +22 -0
- data/ext/xml/ruby_xml_sax_parser.c +181 -0
- data/ext/xml/ruby_xml_sax_parser.h +21 -0
- data/ext/xml/ruby_xml_schema.c +142 -0
- data/ext/xml/ruby_xml_schema.h +16 -0
- data/ext/xml/ruby_xml_tree.c +43 -0
- data/ext/xml/ruby_xml_tree.h +12 -0
- data/ext/xml/ruby_xml_xinclude.c +20 -0
- data/ext/xml/ruby_xml_xinclude.h +13 -0
- data/ext/xml/ruby_xml_xpath.c +357 -0
- data/ext/xml/ruby_xml_xpath.h +24 -0
- data/ext/xml/ruby_xml_xpath_context.c +124 -0
- data/ext/xml/ruby_xml_xpath_context.h +24 -0
- data/ext/xml/ruby_xml_xpointer.c +100 -0
- data/ext/xml/ruby_xml_xpointer.h +27 -0
- data/ext/xml/ruby_xml_xpointer_context.c +22 -0
- data/ext/xml/ruby_xml_xpointer_context.h +18 -0
- data/tests/copy_bug.rb +21 -0
- data/tests/dtd-test.rb +24 -0
- data/tests/model/default_validation_bug.rb +0 -0
- data/tests/model/rubynet.xml +78 -0
- data/tests/model/rubynet_project +13 -0
- data/tests/model/xinclude.xml +5 -0
- data/tests/runner.rb +13 -0
- data/tests/schema-test.rb +74 -0
- data/tests/tc_default_validation.rb +0 -0
- data/tests/tc_xml_document.rb +51 -0
- data/tests/tc_xml_document_write.rb +25 -0
- data/tests/tc_xml_document_write2.rb +55 -0
- data/tests/tc_xml_document_write3.rb +97 -0
- data/tests/tc_xml_node.rb +59 -0
- data/tests/tc_xml_node2.rb +26 -0
- data/tests/tc_xml_node_set.rb +25 -0
- data/tests/tc_xml_node_xlink.rb +28 -0
- data/tests/tc_xml_parser.rb +175 -0
- data/tests/tc_xml_parser2.rb +17 -0
- data/tests/tc_xml_parser3.rb +23 -0
- data/tests/tc_xml_parser4.rb +33 -0
- data/tests/tc_xml_parser5.rb +27 -0
- data/tests/tc_xml_parser6.rb +23 -0
- data/tests/tc_xml_parser7.rb +28 -0
- data/tests/tc_xml_parser_context.rb +89 -0
- data/tests/tc_xml_xinclude.rb +30 -0
- data/tests/tc_xml_xpath.rb +23 -0
- data/tests/tc_xml_xpointer.rb +78 -0
- metadata +144 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
/* $Id: ruby_xml_document.h,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
|
2
|
+
|
3
|
+
/* Please see the LICENSE file for copyright and distribution information */
|
4
|
+
|
5
|
+
#ifndef __RUBY_XML_DOCUMENT__
|
6
|
+
#define __RUBY_XML_DOCUMENT__
|
7
|
+
|
8
|
+
extern VALUE cXMLDocument;
|
9
|
+
|
10
|
+
typedef struct rxp_document {
|
11
|
+
xmlDocPtr doc; /* Tree/DOM interface */
|
12
|
+
int data_type; /* The data type referenced by *data */
|
13
|
+
void *data; /* Pointer to an external structure of options */
|
14
|
+
int is_ptr; /* Determines if this object owns its data or points to it someplace else */
|
15
|
+
VALUE xmlver; /* T_STRING with the xml version */
|
16
|
+
} ruby_xml_document;
|
17
|
+
|
18
|
+
VALUE ruby_xml_document_filename_get(VALUE self);
|
19
|
+
void ruby_xml_document_free(ruby_xml_document *rxd);
|
20
|
+
VALUE ruby_xml_document_new(VALUE class, xmlDocPtr doc);
|
21
|
+
VALUE ruby_xml_document_new2(VALUE class, VALUE xmlver);
|
22
|
+
VALUE ruby_xml_document_new3(VALUE class);
|
23
|
+
VALUE ruby_xml_document_new4(VALUE class, xmlDocPtr doc);
|
24
|
+
VALUE ruby_xml_document_root_get(VALUE self);
|
25
|
+
void ruby_init_xml_document(void);
|
26
|
+
|
27
|
+
#endif
|
@@ -0,0 +1,168 @@
|
|
1
|
+
#include "libxml.h"
|
2
|
+
#include "ruby_xml_dtd.h"
|
3
|
+
|
4
|
+
VALUE cXMLDtd;
|
5
|
+
|
6
|
+
void
|
7
|
+
ruby_xml_dtd_free(ruby_xml_dtd *rxdtd) {
|
8
|
+
if (rxdtd->dtd != NULL) {
|
9
|
+
xmlFreeDtd(rxdtd->dtd);
|
10
|
+
rxdtd->dtd = NULL;
|
11
|
+
}
|
12
|
+
|
13
|
+
free(rxdtd);
|
14
|
+
}
|
15
|
+
|
16
|
+
static void
|
17
|
+
ruby_xml_dtd_mark(ruby_xml_dtd *rxdtd) {
|
18
|
+
return;
|
19
|
+
//if (rxdtd == NULL) return;
|
20
|
+
//if (!NIL_P(rxd->xmlver)) rb_gc_mark(rxd->xmlver);
|
21
|
+
}
|
22
|
+
|
23
|
+
/*
|
24
|
+
* call-seq:
|
25
|
+
* XML::DTD.new("public system") => dtd
|
26
|
+
* XML::DTD.new("public", "system") => dtd
|
27
|
+
*
|
28
|
+
* Create a new DTD from the specified public and system
|
29
|
+
* identifiers.
|
30
|
+
*/
|
31
|
+
VALUE
|
32
|
+
ruby_xml_dtd_initialize(int argc, VALUE *argv, VALUE class) {
|
33
|
+
ruby_xml_dtd *rxdtd;
|
34
|
+
VALUE external, system, dtd_string;
|
35
|
+
xmlParserInputBufferPtr buffer;
|
36
|
+
xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
|
37
|
+
xmlChar *new_string;
|
38
|
+
|
39
|
+
// 1 argument -- string --> parsujeme jako dtd
|
40
|
+
// 2 argumenty -- public, system --> bude se hledat
|
41
|
+
switch (argc) {
|
42
|
+
case 2:
|
43
|
+
rb_scan_args(argc, argv, "20", &external, &system);
|
44
|
+
|
45
|
+
Check_Type(external, T_STRING);
|
46
|
+
Check_Type(system, T_STRING);
|
47
|
+
rxdtd = ALLOC(ruby_xml_dtd);
|
48
|
+
rxdtd->dtd = xmlParseDTD( (xmlChar*)StringValuePtr(external),
|
49
|
+
(xmlChar*)StringValuePtr(system) );
|
50
|
+
if (rxdtd->dtd == NULL) {
|
51
|
+
free(rxdtd);
|
52
|
+
return(Qfalse);
|
53
|
+
}
|
54
|
+
|
55
|
+
xmlSetTreeDoc( (xmlNodePtr)rxdtd->dtd, NULL );
|
56
|
+
return( Data_Wrap_Struct(cXMLDtd, ruby_xml_dtd_mark, ruby_xml_dtd_free, rxdtd) );
|
57
|
+
break;
|
58
|
+
|
59
|
+
/*
|
60
|
+
SV *
|
61
|
+
new(CLASS, external, system)
|
62
|
+
char * CLASS
|
63
|
+
char * external
|
64
|
+
char * system
|
65
|
+
ALIAS:
|
66
|
+
parse_uri = 1
|
67
|
+
PREINIT:
|
68
|
+
xmlDtdPtr dtd = NULL;
|
69
|
+
CODE:
|
70
|
+
LibXML_error = sv_2mortal(newSVpv("", 0));
|
71
|
+
dtd = xmlParseDTD((const xmlChar*)external, (const xmlChar*)system);
|
72
|
+
if ( dtd == NULL ) {
|
73
|
+
XSRETURN_UNDEF;
|
74
|
+
}
|
75
|
+
xmlSetTreeDoc((xmlNodePtr)dtd, NULL);
|
76
|
+
RETVAL = PmmNodeToSv( (xmlNodePtr) dtd, NULL );
|
77
|
+
OUTPUT:
|
78
|
+
RETVAL
|
79
|
+
*/
|
80
|
+
|
81
|
+
case 1:
|
82
|
+
|
83
|
+
rb_scan_args(argc, argv, "10", &dtd_string);
|
84
|
+
buffer = xmlAllocParserInputBuffer(enc);
|
85
|
+
//if ( !buffer) return Qnil
|
86
|
+
new_string = xmlStrdup((xmlChar*)StringValuePtr(dtd_string));
|
87
|
+
xmlParserInputBufferPush(buffer, xmlStrlen(new_string), (const char*)new_string);
|
88
|
+
|
89
|
+
rxdtd = ALLOC(ruby_xml_dtd);
|
90
|
+
rxdtd->dtd = xmlIOParseDTD(NULL, buffer, enc);
|
91
|
+
|
92
|
+
// NOTE: For some reason freeing this InputBuffer causes a segfault!
|
93
|
+
// xmlFreeParserInputBuffer(buffer);
|
94
|
+
xmlFree(new_string);
|
95
|
+
|
96
|
+
return( Data_Wrap_Struct(cXMLDtd, ruby_xml_dtd_mark, ruby_xml_dtd_free, rxdtd) );
|
97
|
+
|
98
|
+
break;
|
99
|
+
/*
|
100
|
+
SV * parse_string(CLASS, str, ...)
|
101
|
+
char * CLASS
|
102
|
+
char * str
|
103
|
+
PREINIT:
|
104
|
+
STRLEN n_a;
|
105
|
+
xmlDtdPtr res;
|
106
|
+
SV * encoding_sv;
|
107
|
+
xmlParserInputBufferPtr buffer;
|
108
|
+
xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
|
109
|
+
xmlChar * new_string;
|
110
|
+
STRLEN len;
|
111
|
+
CODE:
|
112
|
+
LibXML_init_error();
|
113
|
+
if (items > 2) {
|
114
|
+
encoding_sv = ST(2);
|
115
|
+
if (items > 3) {
|
116
|
+
croak("parse_string: too many parameters");
|
117
|
+
}
|
118
|
+
// warn("getting encoding...\n");
|
119
|
+
enc = xmlParseCharEncoding(SvPV(encoding_sv, n_a));
|
120
|
+
if (enc == XML_CHAR_ENCODING_ERROR) {
|
121
|
+
croak("Parse of encoding %s failed: %s", SvPV(encoding_sv, n_a), SvPV(LibXML_error, n_a));
|
122
|
+
}
|
123
|
+
}
|
124
|
+
buffer = xmlAllocParserInputBuffer(enc);
|
125
|
+
// buffer = xmlParserInputBufferCreateMem(str, xmlStrlen(str), enc);
|
126
|
+
if ( !buffer)
|
127
|
+
croak("cant create buffer!\n" );
|
128
|
+
|
129
|
+
new_string = xmlStrdup((const xmlChar*)str);
|
130
|
+
xmlParserInputBufferPush(buffer, xmlStrlen(new_string), (const char*)new_string);
|
131
|
+
|
132
|
+
res = xmlIOParseDTD(NULL, buffer, enc);
|
133
|
+
|
134
|
+
// NOTE: For some reason freeing this InputBuffer causes a segfault!
|
135
|
+
// xmlFreeParserInputBuffer(buffer);
|
136
|
+
xmlFree(new_string);
|
137
|
+
|
138
|
+
sv_2mortal( LibXML_error );
|
139
|
+
LibXML_croak_error();
|
140
|
+
|
141
|
+
if (res == NULL) {
|
142
|
+
croak("no DTD parsed!");
|
143
|
+
}
|
144
|
+
RETVAL = PmmNodeToSv((xmlNodePtr)res, NULL);
|
145
|
+
OUTPUT:
|
146
|
+
RETVAL
|
147
|
+
*/
|
148
|
+
|
149
|
+
default:
|
150
|
+
rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
|
151
|
+
}
|
152
|
+
|
153
|
+
//docobj = ruby_xml_document_new2(cXMLDocument, xmlver);
|
154
|
+
return Qnil;
|
155
|
+
}
|
156
|
+
|
157
|
+
// Rdoc needs to know
|
158
|
+
#ifdef RDOC_NEVER_DEFINED
|
159
|
+
mXML = rb_define_module("XML");
|
160
|
+
#endif
|
161
|
+
|
162
|
+
void
|
163
|
+
ruby_init_xml_dtd(void) {
|
164
|
+
cXMLDtd = rb_define_class_under(mXML, "Dtd", rb_cObject);
|
165
|
+
rb_define_singleton_method(cXMLDtd, "new", ruby_xml_dtd_initialize, -1);
|
166
|
+
//rb_define_method(cXMLDocument, "xinclude", ruby_xml_document_xinclude, 0);
|
167
|
+
}
|
168
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#ifndef __RUBY_XML_DTD__
|
2
|
+
#define __RUBY_XML_DTD__
|
3
|
+
|
4
|
+
extern VALUE cXMLDtd;
|
5
|
+
|
6
|
+
typedef struct rxp_dtd {
|
7
|
+
xmlDtdPtr dtd; /* DTD interface */
|
8
|
+
//int data_type; /* The data type referenced by *data */
|
9
|
+
//void *data; /* Pointer to an external structure of options */
|
10
|
+
//int is_ptr; /* Determines if this object owns its data or points to it someplace else */
|
11
|
+
//VALUE xmlver; /* T_STRING with the xml version */
|
12
|
+
} ruby_xml_dtd;
|
13
|
+
|
14
|
+
void ruby_init_xml_dtd(void);
|
15
|
+
void ruby_dtd_free(ruby_xml_dtd *rxdtd);
|
16
|
+
|
17
|
+
#endif
|
@@ -0,0 +1,167 @@
|
|
1
|
+
|
2
|
+
/* ruby support for custom scheme handlers */
|
3
|
+
/* Author: Martin Povolny (xpovolny@fi.muni.cz) */
|
4
|
+
|
5
|
+
#include "libxml.h"
|
6
|
+
#include "ruby_xml_input_cbg.h"
|
7
|
+
|
8
|
+
static ic_scheme *first_scheme = 0;
|
9
|
+
|
10
|
+
int ic_match (char const *filename) {
|
11
|
+
ic_scheme *scheme;
|
12
|
+
|
13
|
+
//fprintf( stderr, "ic_match: %s\n", filename );
|
14
|
+
|
15
|
+
scheme = first_scheme;
|
16
|
+
while (0 != scheme) {
|
17
|
+
if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST scheme->scheme_name, scheme->name_len)) {
|
18
|
+
return 1;
|
19
|
+
}
|
20
|
+
scheme = scheme->next_scheme;
|
21
|
+
}
|
22
|
+
return 0;
|
23
|
+
}
|
24
|
+
|
25
|
+
void* ic_open (char const *filename) {
|
26
|
+
ic_doc_context *ic_doc;
|
27
|
+
ic_scheme *scheme;
|
28
|
+
VALUE res;
|
29
|
+
|
30
|
+
scheme = first_scheme;
|
31
|
+
while (0 != scheme) {
|
32
|
+
if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST scheme->scheme_name, scheme->name_len)) {
|
33
|
+
ic_doc = (ic_doc_context*)malloc( sizeof(ic_doc_context) );
|
34
|
+
|
35
|
+
// MUFF res = rb_funcall(
|
36
|
+
// rb_funcall( rb_mKernel,
|
37
|
+
// rb_intern("const_get"), 1,
|
38
|
+
// rb_str_new2(scheme->class) ),
|
39
|
+
// rb_intern("document_query"), 1, rb_str_new2(filename) );
|
40
|
+
res = rb_funcall( scheme->class,
|
41
|
+
rb_intern("document_query"),
|
42
|
+
1,
|
43
|
+
rb_str_new2(filename) );
|
44
|
+
|
45
|
+
ic_doc->buffer = strdup( StringValuePtr(res) );
|
46
|
+
|
47
|
+
ic_doc->bpos = ic_doc->buffer;
|
48
|
+
ic_doc->remaining = strlen(ic_doc->buffer);
|
49
|
+
return ic_doc;
|
50
|
+
}
|
51
|
+
scheme = scheme->next_scheme;
|
52
|
+
}
|
53
|
+
return 0;
|
54
|
+
}
|
55
|
+
|
56
|
+
int ic_read (void *context, char *buffer, int len) {
|
57
|
+
ic_doc_context *ic_doc;
|
58
|
+
int ret_len;
|
59
|
+
ic_doc = (ic_doc_context*)context;
|
60
|
+
|
61
|
+
if (len >= ic_doc->remaining) {
|
62
|
+
ret_len = ic_doc->remaining;
|
63
|
+
} else {
|
64
|
+
ret_len = len;
|
65
|
+
}
|
66
|
+
ic_doc->remaining -= ret_len;
|
67
|
+
strncpy( buffer, ic_doc->bpos, ret_len );
|
68
|
+
ic_doc->bpos += ret_len;
|
69
|
+
|
70
|
+
return ret_len;
|
71
|
+
}
|
72
|
+
|
73
|
+
int ic_close (void *context) {
|
74
|
+
free( ((ic_doc_context*)context)->buffer );
|
75
|
+
free( context );
|
76
|
+
return 1;
|
77
|
+
}
|
78
|
+
|
79
|
+
VALUE input_callbacks_register_input_callbacks() {
|
80
|
+
xmlRegisterInputCallbacks( ic_match, ic_open, ic_read, ic_close );
|
81
|
+
return(Qtrue);
|
82
|
+
}
|
83
|
+
|
84
|
+
VALUE
|
85
|
+
input_callbacks_add_scheme (VALUE self, VALUE scheme_name, VALUE class) {
|
86
|
+
ic_scheme *scheme;
|
87
|
+
|
88
|
+
Check_Type(scheme_name, T_STRING);
|
89
|
+
//MUFF Check_Type(class, T_STRING);
|
90
|
+
|
91
|
+
scheme = (ic_scheme*)malloc(sizeof(ic_scheme));
|
92
|
+
scheme->next_scheme = 0;
|
93
|
+
scheme->scheme_name = strdup(StringValuePtr(scheme_name)); /* TODO alloc, dealloc */
|
94
|
+
scheme->name_len = strlen(scheme->scheme_name);
|
95
|
+
//MUFF scheme->class = strdup(StringValuePtr(class)); /* TODO alloc, dealloc */
|
96
|
+
scheme->class = class; /* TODO alloc, dealloc */
|
97
|
+
|
98
|
+
//fprintf( stderr, "registered: %s, %d, %s\n", scheme->scheme_name, scheme->name_len, scheme->class );
|
99
|
+
|
100
|
+
if (0 == first_scheme)
|
101
|
+
first_scheme = scheme;
|
102
|
+
else {
|
103
|
+
ic_scheme *pos;
|
104
|
+
pos = first_scheme;
|
105
|
+
while (0 != pos->next_scheme)
|
106
|
+
pos = pos->next_scheme;
|
107
|
+
pos->next_scheme = scheme;
|
108
|
+
}
|
109
|
+
|
110
|
+
return(Qtrue);
|
111
|
+
}
|
112
|
+
|
113
|
+
VALUE
|
114
|
+
input_callbacks_remove_scheme (VALUE self, VALUE scheme_name) {
|
115
|
+
char *name;
|
116
|
+
ic_scheme *save_scheme, *scheme;
|
117
|
+
|
118
|
+
Check_Type(scheme_name, T_STRING);
|
119
|
+
name = StringValuePtr(scheme_name);
|
120
|
+
|
121
|
+
if (0 == first_scheme)
|
122
|
+
return Qfalse;
|
123
|
+
|
124
|
+
/* check the first one */
|
125
|
+
if (!strncmp(name, first_scheme->scheme_name, first_scheme->name_len)) {
|
126
|
+
save_scheme = first_scheme->next_scheme;
|
127
|
+
|
128
|
+
free(first_scheme->scheme_name);
|
129
|
+
//MUFF free(first_scheme->class);
|
130
|
+
free(first_scheme);
|
131
|
+
|
132
|
+
first_scheme = save_scheme;
|
133
|
+
return Qtrue;
|
134
|
+
}
|
135
|
+
|
136
|
+
scheme = first_scheme;
|
137
|
+
while (0 != scheme->next_scheme) {
|
138
|
+
if ( !strncmp( name, scheme->next_scheme->scheme_name, scheme->next_scheme->name_len ) ) {
|
139
|
+
save_scheme = scheme->next_scheme->next_scheme;
|
140
|
+
|
141
|
+
free(scheme->next_scheme->scheme_name);
|
142
|
+
//MUFF free(scheme->next_scheme->class);
|
143
|
+
free(scheme->next_scheme);
|
144
|
+
|
145
|
+
scheme->next_scheme = save_scheme;
|
146
|
+
return Qtrue;
|
147
|
+
}
|
148
|
+
scheme = scheme->next_scheme;
|
149
|
+
}
|
150
|
+
return Qfalse;
|
151
|
+
}
|
152
|
+
|
153
|
+
// Rdoc needs to know
|
154
|
+
#ifdef RDOC_NEVER_DEFINED
|
155
|
+
mXML = rb_define_module("XML");
|
156
|
+
#endif
|
157
|
+
|
158
|
+
void
|
159
|
+
ruby_init_input_callbacks(void) {
|
160
|
+
VALUE cInputCallbacks;
|
161
|
+
cInputCallbacks = rb_define_class_under(mXML, "InputCallbacks", rb_cObject);
|
162
|
+
|
163
|
+
/* Class Methods */
|
164
|
+
rb_define_singleton_method(cInputCallbacks, "register", input_callbacks_register_input_callbacks, 0);
|
165
|
+
rb_define_singleton_method(cInputCallbacks, "add_scheme", input_callbacks_add_scheme, 2);
|
166
|
+
rb_define_singleton_method(cInputCallbacks, "remove_scheme", input_callbacks_remove_scheme, 1);
|
167
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#ifndef _INPUT_CBG_
|
2
|
+
#define _INPUT_CBG_
|
3
|
+
|
4
|
+
void ruby_init_input_callbacks(void);
|
5
|
+
|
6
|
+
typedef struct ic_doc_context {
|
7
|
+
char *buffer;
|
8
|
+
char *bpos;
|
9
|
+
int remaining;
|
10
|
+
} ic_doc_context;
|
11
|
+
|
12
|
+
typedef struct ic_scheme {
|
13
|
+
char *scheme_name;
|
14
|
+
//MUFF char *class;
|
15
|
+
VALUE class;
|
16
|
+
int name_len;
|
17
|
+
|
18
|
+
struct ic_scheme *next_scheme;
|
19
|
+
} ic_scheme;
|
20
|
+
|
21
|
+
#endif
|
@@ -0,0 +1,2052 @@
|
|
1
|
+
/* $Id: ruby_xml_node.c,v 1.1 2006/02/21 20:40:16 roscopeco Exp $ */
|
2
|
+
|
3
|
+
/* Please see the LICENSE file for copyright and distribution information */
|
4
|
+
|
5
|
+
#include "libxml.h"
|
6
|
+
#include "ruby_xml_node.h"
|
7
|
+
|
8
|
+
VALUE cXMLNode;
|
9
|
+
VALUE eXMLNodeSetNamespace;
|
10
|
+
VALUE eXMLNodeFailedModify;
|
11
|
+
VALUE eXMLNodeUnknownType;
|
12
|
+
|
13
|
+
/*
|
14
|
+
* call-seq:
|
15
|
+
* node.attribute? => (true|false)
|
16
|
+
*
|
17
|
+
* Determine whether this is an attribute node,
|
18
|
+
*/
|
19
|
+
VALUE
|
20
|
+
ruby_xml_node_attribute_q(VALUE self) {
|
21
|
+
ruby_xml_node *rxn;
|
22
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
23
|
+
if (rxn->node->type == XML_ATTRIBUTE_NODE)
|
24
|
+
return(Qtrue);
|
25
|
+
else
|
26
|
+
return(Qfalse);
|
27
|
+
}
|
28
|
+
|
29
|
+
|
30
|
+
/*
|
31
|
+
* call-seq:
|
32
|
+
* node.attribute_decl? => (true|false)
|
33
|
+
*
|
34
|
+
* Determine whether this is an attribute declaration node,
|
35
|
+
*/
|
36
|
+
VALUE
|
37
|
+
ruby_xml_node_attribute_decl_q(VALUE self) {
|
38
|
+
ruby_xml_node *rxn;
|
39
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
40
|
+
if (rxn->node->type == XML_ATTRIBUTE_DECL)
|
41
|
+
return(Qtrue);
|
42
|
+
else
|
43
|
+
return(Qfalse);
|
44
|
+
}
|
45
|
+
|
46
|
+
|
47
|
+
/*
|
48
|
+
* call-seq:
|
49
|
+
* node.base => "uri"
|
50
|
+
*
|
51
|
+
* Obtain this node's base URI.
|
52
|
+
*/
|
53
|
+
VALUE
|
54
|
+
ruby_xml_node_base_get(VALUE self) {
|
55
|
+
ruby_xml_node *rxn;
|
56
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
57
|
+
if (rxn->node->doc == NULL)
|
58
|
+
return(Qnil);
|
59
|
+
|
60
|
+
// TODO some NULL checking, raises ArgumentError in Ruby:
|
61
|
+
// ArgumentError: NULL pointer given
|
62
|
+
|
63
|
+
return(rb_str_new2((const char*)xmlNodeGetBase(rxn->node->doc, rxn->node)));
|
64
|
+
}
|
65
|
+
|
66
|
+
|
67
|
+
// TODO node_base_set should support setting back to nil
|
68
|
+
|
69
|
+
/*
|
70
|
+
* call-seq:
|
71
|
+
* node.base = "uri"
|
72
|
+
*
|
73
|
+
* Set this node's base URI.
|
74
|
+
*/
|
75
|
+
VALUE
|
76
|
+
ruby_xml_node_base_set(VALUE self, VALUE uri) {
|
77
|
+
ruby_xml_node *node;
|
78
|
+
|
79
|
+
Check_Type(uri, T_STRING);
|
80
|
+
Data_Get_Struct(self, ruby_xml_node, node);
|
81
|
+
if (node->node->doc == NULL)
|
82
|
+
return(Qnil);
|
83
|
+
|
84
|
+
xmlNodeSetBase(node->node, (xmlChar*)StringValuePtr(uri));
|
85
|
+
return(Qtrue);
|
86
|
+
}
|
87
|
+
|
88
|
+
|
89
|
+
/*
|
90
|
+
* call-seq:
|
91
|
+
* node.cdata? => (true|false)
|
92
|
+
*
|
93
|
+
* Determine whether this is a #CDATA node
|
94
|
+
*/
|
95
|
+
VALUE
|
96
|
+
ruby_xml_node_cdata_q(VALUE self) {
|
97
|
+
ruby_xml_node *rxn;
|
98
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
99
|
+
if (rxn->node->type == XML_CDATA_SECTION_NODE)
|
100
|
+
return(Qtrue);
|
101
|
+
else
|
102
|
+
return(Qfalse);
|
103
|
+
}
|
104
|
+
|
105
|
+
|
106
|
+
/*
|
107
|
+
* call-seq:
|
108
|
+
* node.comment? => (true|false)
|
109
|
+
*
|
110
|
+
* Determine whether this is a comment node
|
111
|
+
*/
|
112
|
+
VALUE
|
113
|
+
ruby_xml_node_comment_q(VALUE self) {
|
114
|
+
ruby_xml_node *rxn;
|
115
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
116
|
+
if (rxn->node->type == XML_COMMENT_NODE)
|
117
|
+
return(Qtrue);
|
118
|
+
else
|
119
|
+
return(Qfalse);
|
120
|
+
}
|
121
|
+
|
122
|
+
|
123
|
+
/*
|
124
|
+
* call-seq:
|
125
|
+
* node << ("string" | node)
|
126
|
+
*
|
127
|
+
* Add the specified string or XML::Node to this node's
|
128
|
+
* content.
|
129
|
+
*/
|
130
|
+
VALUE
|
131
|
+
ruby_xml_node_content_add(VALUE self, VALUE obj) {
|
132
|
+
ruby_xml_node *node;
|
133
|
+
VALUE str;
|
134
|
+
|
135
|
+
Data_Get_Struct(self, ruby_xml_node, node);
|
136
|
+
if (rb_obj_is_kind_of(obj, cXMLNode)) {
|
137
|
+
return(ruby_xml_node_child_set(self, obj));
|
138
|
+
} else if (TYPE(obj) == T_STRING) {
|
139
|
+
xmlNodeAddContent(node->node, (xmlChar*)StringValuePtr(obj));
|
140
|
+
return(obj);
|
141
|
+
} else {
|
142
|
+
str = rb_obj_as_string(obj);
|
143
|
+
if (NIL_P(str) || TYPE(str) != T_STRING)
|
144
|
+
rb_raise(rb_eTypeError, "invalid argumnt: must be string or XML::Node");
|
145
|
+
|
146
|
+
xmlNodeAddContent(node->node, (xmlChar*)StringValuePtr(str));
|
147
|
+
return(obj);
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
151
|
+
|
152
|
+
/*
|
153
|
+
* call-seq:
|
154
|
+
* node.content => "string"
|
155
|
+
*
|
156
|
+
* Obtain this node's content as a string.
|
157
|
+
*/
|
158
|
+
VALUE
|
159
|
+
ruby_xml_node_content_get(VALUE self) {
|
160
|
+
ruby_xml_node *rxn;
|
161
|
+
|
162
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
163
|
+
if (rxn->node->type == XML_ELEMENT_NODE || rxn->node->content == NULL)
|
164
|
+
return(Qnil);
|
165
|
+
else {
|
166
|
+
return(rb_str_new2((const char*)rxn->node->content));
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
170
|
+
/////////////////////////////////////////////
|
171
|
+
// TODO may be bugged:
|
172
|
+
//
|
173
|
+
// node.content = "123"
|
174
|
+
// node.content => nil
|
175
|
+
// node.content_stripped => nil
|
176
|
+
// node.to_s => "<head xml:base=\"123\">wow</head>"
|
177
|
+
|
178
|
+
|
179
|
+
/*
|
180
|
+
* call-seq:
|
181
|
+
* node.content = "string"
|
182
|
+
*
|
183
|
+
* Set this node's content to the specified string.
|
184
|
+
*/
|
185
|
+
VALUE
|
186
|
+
ruby_xml_node_content_set(VALUE self, VALUE content) {
|
187
|
+
ruby_xml_node *node;
|
188
|
+
|
189
|
+
Check_Type(content, T_STRING);
|
190
|
+
Data_Get_Struct(self, ruby_xml_node, node);
|
191
|
+
xmlNodeSetContent(node->node, (xmlChar*)StringValuePtr(content));
|
192
|
+
return(Qtrue);
|
193
|
+
}
|
194
|
+
|
195
|
+
|
196
|
+
/////////////////////////////////////////////////////
|
197
|
+
// TODO may be bugged: see above
|
198
|
+
//
|
199
|
+
|
200
|
+
/*
|
201
|
+
* call-seq:
|
202
|
+
* node.content_stripped => "string"
|
203
|
+
*
|
204
|
+
* Obtain this node's stripped content.
|
205
|
+
*/
|
206
|
+
VALUE
|
207
|
+
ruby_xml_node_content_stripped_get(VALUE self) {
|
208
|
+
ruby_xml_node *rxn;
|
209
|
+
|
210
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
211
|
+
if (rxn->node->content == NULL)
|
212
|
+
return(Qnil);
|
213
|
+
else
|
214
|
+
return(rb_str_new2((const char*)xmlNodeGetContent(rxn->node)));
|
215
|
+
}
|
216
|
+
|
217
|
+
////////////////////////////////////////////////////
|
218
|
+
// TODO This whole child thing seems to work in some odd ways.
|
219
|
+
// Try setting child= to a node with multiple children,
|
220
|
+
// then get it back through child= .
|
221
|
+
|
222
|
+
/*
|
223
|
+
* call-seq:
|
224
|
+
* node.child => node
|
225
|
+
*
|
226
|
+
* Obtain this node's first child node, if any.
|
227
|
+
*/
|
228
|
+
VALUE
|
229
|
+
ruby_xml_node_child_get(VALUE self) {
|
230
|
+
ruby_xml_node *node;
|
231
|
+
xmlNodePtr tmp;
|
232
|
+
|
233
|
+
Data_Get_Struct(self, ruby_xml_node, node);
|
234
|
+
|
235
|
+
switch (node->node->type) {
|
236
|
+
case XML_ELEMENT_NODE:
|
237
|
+
case XML_ENTITY_REF_NODE:
|
238
|
+
case XML_ENTITY_NODE:
|
239
|
+
case XML_PI_NODE:
|
240
|
+
case XML_COMMENT_NODE:
|
241
|
+
case XML_DOCUMENT_NODE:
|
242
|
+
#ifdef LIBXML_DOCB_ENABLED
|
243
|
+
case XML_DOCB_DOCUMENT_NODE:
|
244
|
+
#endif
|
245
|
+
case XML_HTML_DOCUMENT_NODE:
|
246
|
+
case XML_DTD_NODE:
|
247
|
+
tmp = node->node->children;
|
248
|
+
break;
|
249
|
+
case XML_ATTRIBUTE_NODE:
|
250
|
+
{
|
251
|
+
xmlAttrPtr attr = (xmlAttrPtr) node->node;
|
252
|
+
tmp = attr->children;
|
253
|
+
break;
|
254
|
+
}
|
255
|
+
default:
|
256
|
+
tmp = NULL;
|
257
|
+
break;
|
258
|
+
}
|
259
|
+
|
260
|
+
if (tmp == NULL)
|
261
|
+
return(Qnil);
|
262
|
+
else
|
263
|
+
return(ruby_xml_node_new2(cXMLNode, node->xd, tmp));
|
264
|
+
}
|
265
|
+
|
266
|
+
|
267
|
+
/*
|
268
|
+
* call-seq:
|
269
|
+
* node.child? => (true|false)
|
270
|
+
*
|
271
|
+
* Determine whether this node has at least one child.
|
272
|
+
*/
|
273
|
+
VALUE
|
274
|
+
ruby_xml_node_child_q(VALUE self) {
|
275
|
+
ruby_xml_node *rxn;
|
276
|
+
xmlNodePtr node;
|
277
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
278
|
+
|
279
|
+
node = NULL;
|
280
|
+
switch (rxn->node->type) {
|
281
|
+
case XML_ELEMENT_NODE:
|
282
|
+
case XML_ENTITY_REF_NODE:
|
283
|
+
case XML_ENTITY_NODE:
|
284
|
+
case XML_PI_NODE:
|
285
|
+
case XML_COMMENT_NODE:
|
286
|
+
case XML_DOCUMENT_NODE:
|
287
|
+
#ifdef LIBXML_DOCB_ENABLED
|
288
|
+
case XML_DOCB_DOCUMENT_NODE:
|
289
|
+
#endif
|
290
|
+
case XML_HTML_DOCUMENT_NODE:
|
291
|
+
case XML_DTD_NODE:
|
292
|
+
node = rxn->node->children;
|
293
|
+
break;
|
294
|
+
case XML_ATTRIBUTE_NODE:
|
295
|
+
{
|
296
|
+
xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
|
297
|
+
node = attr->children;
|
298
|
+
break;
|
299
|
+
}
|
300
|
+
default:
|
301
|
+
node = NULL;
|
302
|
+
}
|
303
|
+
|
304
|
+
if (node == NULL)
|
305
|
+
return(Qfalse);
|
306
|
+
else
|
307
|
+
return(Qtrue);
|
308
|
+
}
|
309
|
+
|
310
|
+
|
311
|
+
/*
|
312
|
+
* call-seq:
|
313
|
+
* node.child = node
|
314
|
+
*
|
315
|
+
* Set a child node for this node.
|
316
|
+
*/
|
317
|
+
VALUE
|
318
|
+
ruby_xml_node_child_set(VALUE self, VALUE rnode) {
|
319
|
+
ruby_xml_node *cnode, *pnode;
|
320
|
+
xmlNodePtr ret;
|
321
|
+
|
322
|
+
if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
|
323
|
+
rb_raise(rb_eTypeError, "Must pass an XML::Node object");
|
324
|
+
|
325
|
+
Data_Get_Struct(self, ruby_xml_node, pnode);
|
326
|
+
Data_Get_Struct(rnode, ruby_xml_node, cnode);
|
327
|
+
|
328
|
+
ret = xmlAddChild(pnode->node, cnode->node);
|
329
|
+
if (ret == NULL)
|
330
|
+
rb_raise(eXMLNodeFailedModify, "unable to add a child to the document");
|
331
|
+
|
332
|
+
ruby_xml_node_set_ptr(rnode, 1);
|
333
|
+
return(ruby_xml_node_new2(cXMLNode, pnode->xd, ret));
|
334
|
+
}
|
335
|
+
|
336
|
+
////////////////////////////////////////////////
|
337
|
+
// TODO new Documents seem to be created quite readily...
|
338
|
+
|
339
|
+
/*
|
340
|
+
* call-seq:
|
341
|
+
* node.doc => document
|
342
|
+
*
|
343
|
+
* Obtain the XML::Document this node belongs to.
|
344
|
+
*/
|
345
|
+
VALUE
|
346
|
+
ruby_xml_node_doc(VALUE self) {
|
347
|
+
ruby_xml_document *rxd;
|
348
|
+
ruby_xml_node *rxn;
|
349
|
+
xmlDocPtr doc;
|
350
|
+
VALUE docobj;
|
351
|
+
|
352
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
353
|
+
|
354
|
+
switch (rxn->node->type) {
|
355
|
+
case XML_DOCUMENT_NODE:
|
356
|
+
#ifdef LIBXML_DOCB_ENABLED
|
357
|
+
case XML_DOCB_DOCUMENT_NODE:
|
358
|
+
#endif
|
359
|
+
case XML_HTML_DOCUMENT_NODE:
|
360
|
+
doc = NULL;
|
361
|
+
break;
|
362
|
+
case XML_ATTRIBUTE_NODE:
|
363
|
+
{
|
364
|
+
xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
|
365
|
+
doc = attr->doc;
|
366
|
+
break;
|
367
|
+
}
|
368
|
+
case XML_NAMESPACE_DECL:
|
369
|
+
doc = NULL;
|
370
|
+
break;
|
371
|
+
default:
|
372
|
+
doc = rxn->node->doc;
|
373
|
+
break;
|
374
|
+
}
|
375
|
+
|
376
|
+
if (doc == NULL)
|
377
|
+
return(Qnil);
|
378
|
+
|
379
|
+
docobj = ruby_xml_document_new(cXMLDocument, doc);
|
380
|
+
Data_Get_Struct(docobj, ruby_xml_document, rxd);
|
381
|
+
rxd->is_ptr = 1;
|
382
|
+
return(docobj);
|
383
|
+
}
|
384
|
+
|
385
|
+
|
386
|
+
/*
|
387
|
+
* call-seq:
|
388
|
+
* node.docbook? => (true|false)
|
389
|
+
*
|
390
|
+
* Determine whether this is a docbook node.
|
391
|
+
*/
|
392
|
+
VALUE
|
393
|
+
ruby_xml_node_docbook_doc_q(VALUE self) {
|
394
|
+
#ifdef LIBXML_DOCB_ENABLED
|
395
|
+
ruby_xml_node *rxn;
|
396
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
397
|
+
if (rxn->node->type == XML_DOCB_DOCUMENT_NODE)
|
398
|
+
return(Qtrue);
|
399
|
+
else
|
400
|
+
return(Qfalse);
|
401
|
+
#else
|
402
|
+
rb_warn("libxml compiled without docbook support");
|
403
|
+
return(Qfalse);
|
404
|
+
#endif
|
405
|
+
}
|
406
|
+
|
407
|
+
|
408
|
+
/*
|
409
|
+
* call-seq:
|
410
|
+
* node.doctype? => (true|false)
|
411
|
+
*
|
412
|
+
* Determine whether this is a DOCTYPE node.
|
413
|
+
*/
|
414
|
+
VALUE
|
415
|
+
ruby_xml_node_doctype_q(VALUE self) {
|
416
|
+
ruby_xml_node *rxn;
|
417
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
418
|
+
if (rxn->node->type == XML_DOCUMENT_TYPE_NODE)
|
419
|
+
return(Qtrue);
|
420
|
+
else
|
421
|
+
return(Qfalse);
|
422
|
+
}
|
423
|
+
|
424
|
+
|
425
|
+
/*
|
426
|
+
* call-seq:
|
427
|
+
* node.document? => (true|false)
|
428
|
+
*
|
429
|
+
* Determine whether this is a document node.
|
430
|
+
*/
|
431
|
+
VALUE
|
432
|
+
ruby_xml_node_document_q(VALUE self) {
|
433
|
+
ruby_xml_node *rxn;
|
434
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
435
|
+
if (rxn->node->type == XML_DOCUMENT_NODE)
|
436
|
+
return(Qtrue);
|
437
|
+
else
|
438
|
+
return(Qfalse);
|
439
|
+
}
|
440
|
+
|
441
|
+
|
442
|
+
/*
|
443
|
+
* call-seq:
|
444
|
+
* node.dtd? => (true|false)
|
445
|
+
*
|
446
|
+
* Determine whether this is a DTD node.
|
447
|
+
*/
|
448
|
+
VALUE
|
449
|
+
ruby_xml_node_dtd_q(VALUE self) {
|
450
|
+
ruby_xml_node *rxn;
|
451
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
452
|
+
if (rxn->node->type == XML_DTD_NODE)
|
453
|
+
return(Qtrue);
|
454
|
+
else
|
455
|
+
return(Qfalse);
|
456
|
+
}
|
457
|
+
|
458
|
+
|
459
|
+
/*
|
460
|
+
* call-seq:
|
461
|
+
* node.dump => (true|nil)
|
462
|
+
*
|
463
|
+
* Dump this node to stdout.
|
464
|
+
*/
|
465
|
+
VALUE
|
466
|
+
ruby_xml_node_dump(VALUE self) {
|
467
|
+
ruby_xml_node *rxn;
|
468
|
+
xmlBufferPtr buf;
|
469
|
+
|
470
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
471
|
+
|
472
|
+
if (rxn->node->doc == NULL)
|
473
|
+
return(Qnil);
|
474
|
+
|
475
|
+
buf = xmlBufferCreate();
|
476
|
+
xmlNodeDump(buf, rxn->node->doc, rxn->node, 0, 1);
|
477
|
+
xmlBufferDump(stdout, buf);
|
478
|
+
xmlBufferFree(buf);
|
479
|
+
return(Qtrue);
|
480
|
+
}
|
481
|
+
|
482
|
+
|
483
|
+
/*
|
484
|
+
* call-seq:
|
485
|
+
* node.debug_dump => (true|nil)
|
486
|
+
*
|
487
|
+
* Dump this node to stdout, including any debugging
|
488
|
+
* information.
|
489
|
+
*/
|
490
|
+
VALUE
|
491
|
+
ruby_xml_node_debug_dump(VALUE self) {
|
492
|
+
ruby_xml_node *rxn;
|
493
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
494
|
+
|
495
|
+
if (rxn->node->doc == NULL)
|
496
|
+
return(Qnil);
|
497
|
+
|
498
|
+
xmlElemDump(stdout, rxn->node->doc, rxn->node);
|
499
|
+
return(Qtrue);
|
500
|
+
}
|
501
|
+
|
502
|
+
|
503
|
+
/*
|
504
|
+
* call-seq:
|
505
|
+
* node.element? => (true|false)
|
506
|
+
*
|
507
|
+
* Determine whether this is an element node.
|
508
|
+
*/
|
509
|
+
VALUE
|
510
|
+
ruby_xml_node_element_q(VALUE self) {
|
511
|
+
ruby_xml_node *rxn;
|
512
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
513
|
+
if (rxn->node->type == XML_ELEMENT_NODE)
|
514
|
+
return(Qtrue);
|
515
|
+
else
|
516
|
+
return(Qfalse);
|
517
|
+
}
|
518
|
+
|
519
|
+
|
520
|
+
/*
|
521
|
+
* call-seq:
|
522
|
+
* node.element_decl? => (true|false)
|
523
|
+
*
|
524
|
+
* Determine whether this is an element declaration node.
|
525
|
+
*/
|
526
|
+
VALUE
|
527
|
+
ruby_xml_node_element_decl_q(VALUE self) {
|
528
|
+
ruby_xml_node *rxn;
|
529
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
530
|
+
if (rxn->node->type == XML_ELEMENT_DECL)
|
531
|
+
return(Qtrue);
|
532
|
+
else
|
533
|
+
return(Qfalse);
|
534
|
+
}
|
535
|
+
|
536
|
+
|
537
|
+
/*
|
538
|
+
* call-seq:
|
539
|
+
* node.empty? => (true|false)
|
540
|
+
*
|
541
|
+
* Determine whether this node is empty.
|
542
|
+
*/
|
543
|
+
VALUE
|
544
|
+
ruby_xml_node_empty_q(VALUE self) {
|
545
|
+
ruby_xml_node *rxn;
|
546
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
547
|
+
if (rxn->node == NULL)
|
548
|
+
return(Qnil);
|
549
|
+
|
550
|
+
return((xmlIsBlankNode(rxn->node) == 1) ? Qtrue : Qfalse);
|
551
|
+
}
|
552
|
+
|
553
|
+
|
554
|
+
/*
|
555
|
+
* call-seq:
|
556
|
+
* node.entity? => (true|false)
|
557
|
+
*
|
558
|
+
* Determine whether this is an entity node.
|
559
|
+
*/
|
560
|
+
VALUE
|
561
|
+
ruby_xml_node_entity_q(VALUE self) {
|
562
|
+
ruby_xml_node *rxn;
|
563
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
564
|
+
if (rxn->node->type == XML_ENTITY_NODE)
|
565
|
+
return(Qtrue);
|
566
|
+
else
|
567
|
+
return(Qfalse);
|
568
|
+
}
|
569
|
+
|
570
|
+
|
571
|
+
/*
|
572
|
+
* call-seq:
|
573
|
+
* node.entity_ref? => (true|false)
|
574
|
+
*
|
575
|
+
* Determine whether this is an entity reference node.
|
576
|
+
*/
|
577
|
+
VALUE
|
578
|
+
ruby_xml_node_entity_ref_q(VALUE self) {
|
579
|
+
ruby_xml_node *rxn;
|
580
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
581
|
+
if (rxn->node->type == XML_ENTITY_REF_NODE)
|
582
|
+
return(Qtrue);
|
583
|
+
else
|
584
|
+
return(Qfalse);
|
585
|
+
}
|
586
|
+
|
587
|
+
|
588
|
+
/*
|
589
|
+
* call-seq:
|
590
|
+
* node.find(xpath_expr, namespace = [any]) => nodeset
|
591
|
+
*
|
592
|
+
* Find nodes matching the specified xpath expression, optionally
|
593
|
+
* using the specified namespaces. Returns an XML::Node::Set.
|
594
|
+
*/
|
595
|
+
VALUE
|
596
|
+
ruby_xml_node_find(int argc, VALUE *argv, VALUE self) {
|
597
|
+
int i, vargc;
|
598
|
+
VALUE *vargv;
|
599
|
+
|
600
|
+
if (argc > 2 || argc < 1)
|
601
|
+
rb_raise(rb_eArgError, "wrong number of arguments (need 1 or 2)");
|
602
|
+
|
603
|
+
vargc = argc + 1;
|
604
|
+
vargv = ALLOC_N(VALUE, vargc + 1);
|
605
|
+
vargv[0] = self;
|
606
|
+
for (i = 0; i<argc; i++)
|
607
|
+
vargv[i + 1] = argv[i];
|
608
|
+
|
609
|
+
return(ruby_xml_xpath_find2(vargc, vargv));
|
610
|
+
}
|
611
|
+
|
612
|
+
|
613
|
+
/*
|
614
|
+
* call-seq:
|
615
|
+
* node.fragment? => (true|false)
|
616
|
+
*
|
617
|
+
* Determine whether this node is a fragment.
|
618
|
+
*/
|
619
|
+
VALUE
|
620
|
+
ruby_xml_node_fragment_q(VALUE self) {
|
621
|
+
ruby_xml_node *rxn;
|
622
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
623
|
+
if (rxn->node->type == XML_DOCUMENT_FRAG_NODE)
|
624
|
+
return(Qtrue);
|
625
|
+
else
|
626
|
+
return(Qfalse);
|
627
|
+
}
|
628
|
+
|
629
|
+
|
630
|
+
void ruby_xml_node_free(ruby_xml_node *rxn) {
|
631
|
+
if (rxn->node != NULL && !rxn->is_ptr) {
|
632
|
+
xmlUnlinkNode(rxn->node);
|
633
|
+
xmlFreeNode(rxn->node);
|
634
|
+
rxn->node = NULL;
|
635
|
+
}
|
636
|
+
|
637
|
+
free(rxn);
|
638
|
+
}
|
639
|
+
|
640
|
+
|
641
|
+
/*
|
642
|
+
* call-seq:
|
643
|
+
* node.html_doc? => (true|false)
|
644
|
+
*
|
645
|
+
* Determine whether this node is an html document node.
|
646
|
+
*/
|
647
|
+
VALUE
|
648
|
+
ruby_xml_node_html_doc_q(VALUE self) {
|
649
|
+
ruby_xml_node *rxn;
|
650
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
651
|
+
if (rxn->node->type == XML_HTML_DOCUMENT_NODE)
|
652
|
+
return(Qtrue);
|
653
|
+
else
|
654
|
+
return(Qfalse);
|
655
|
+
}
|
656
|
+
|
657
|
+
|
658
|
+
/*
|
659
|
+
* call-seq:
|
660
|
+
* XML::Node.new(name, content = nil) => node
|
661
|
+
*
|
662
|
+
* Create a new node with the specified name, optionally setting
|
663
|
+
* the node's content.
|
664
|
+
*/
|
665
|
+
VALUE
|
666
|
+
ruby_xml_node_initialize(int argc, VALUE *argv, VALUE class) {
|
667
|
+
ruby_xml_node *rxn;
|
668
|
+
VALUE name, node, str;
|
669
|
+
|
670
|
+
str = Qnil;
|
671
|
+
|
672
|
+
switch(argc) {
|
673
|
+
case 2:
|
674
|
+
switch (TYPE(str)) {
|
675
|
+
case T_STRING:
|
676
|
+
str = argv[1];
|
677
|
+
break;
|
678
|
+
default:
|
679
|
+
str = rb_obj_as_string(argv[1]);
|
680
|
+
if (NIL_P(str))
|
681
|
+
Check_Type(str, T_STRING);
|
682
|
+
break;
|
683
|
+
}
|
684
|
+
|
685
|
+
/* Intentionally fall through to case 1: as a way of setting up
|
686
|
+
* the object. Sneaky, but effective. Probably should use a goto
|
687
|
+
* instead. */
|
688
|
+
case 1:
|
689
|
+
name = argv[0];
|
690
|
+
Check_Type(name, T_STRING);
|
691
|
+
node = ruby_xml_node_new(class, NULL);
|
692
|
+
Data_Get_Struct(node, ruby_xml_node, rxn);
|
693
|
+
rxn->node = xmlNewNode(NULL, (xmlChar*)StringValuePtr(name));
|
694
|
+
if (rxn->node == NULL)
|
695
|
+
return(Qnil);
|
696
|
+
|
697
|
+
if (!NIL_P(str))
|
698
|
+
ruby_xml_node_content_set(node, str);
|
699
|
+
|
700
|
+
break;
|
701
|
+
|
702
|
+
default:
|
703
|
+
rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
|
704
|
+
}
|
705
|
+
|
706
|
+
return(node);
|
707
|
+
}
|
708
|
+
|
709
|
+
|
710
|
+
/*
|
711
|
+
* call-seq:
|
712
|
+
* node.lang => "string"
|
713
|
+
*
|
714
|
+
* Obtain the language set for this node, if any.
|
715
|
+
* This is set in XML via the xml:lang attribute.
|
716
|
+
*/
|
717
|
+
VALUE
|
718
|
+
ruby_xml_node_lang_get(VALUE self) {
|
719
|
+
ruby_xml_node *rxn;
|
720
|
+
xmlChar *lang;
|
721
|
+
|
722
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
723
|
+
lang = xmlNodeGetLang(rxn->node);
|
724
|
+
|
725
|
+
if (lang == NULL)
|
726
|
+
return(Qnil);
|
727
|
+
else
|
728
|
+
return(rb_str_new2((const char*)lang));
|
729
|
+
}
|
730
|
+
|
731
|
+
|
732
|
+
// TODO node_lang_set should support setting back to nil
|
733
|
+
|
734
|
+
/*
|
735
|
+
* call-seq:
|
736
|
+
* node.lang = "string"
|
737
|
+
*
|
738
|
+
* Set the language for this node. This affects the value
|
739
|
+
* of the xml:lang attribute.
|
740
|
+
*/
|
741
|
+
VALUE
|
742
|
+
ruby_xml_node_lang_set(VALUE self, VALUE lang) {
|
743
|
+
ruby_xml_node *node;
|
744
|
+
|
745
|
+
Check_Type(lang, T_STRING);
|
746
|
+
Data_Get_Struct(self, ruby_xml_node, node);
|
747
|
+
xmlNodeSetLang(node->node, (xmlChar*)StringValuePtr(lang));
|
748
|
+
|
749
|
+
return(Qtrue);
|
750
|
+
}
|
751
|
+
|
752
|
+
|
753
|
+
/*
|
754
|
+
* call-seq:
|
755
|
+
* node.last => node
|
756
|
+
*
|
757
|
+
* Obtain the last child node of this node, if any.
|
758
|
+
*/
|
759
|
+
VALUE
|
760
|
+
ruby_xml_node_last_get(VALUE self) {
|
761
|
+
ruby_xml_node *rxn;
|
762
|
+
xmlNodePtr node;
|
763
|
+
|
764
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
765
|
+
|
766
|
+
switch (rxn->node->type) {
|
767
|
+
case XML_ELEMENT_NODE:
|
768
|
+
case XML_ENTITY_REF_NODE:
|
769
|
+
case XML_ENTITY_NODE:
|
770
|
+
case XML_PI_NODE:
|
771
|
+
case XML_COMMENT_NODE:
|
772
|
+
case XML_DOCUMENT_NODE:
|
773
|
+
#ifdef LIBXML_DOCB_ENABLED
|
774
|
+
case XML_DOCB_DOCUMENT_NODE:
|
775
|
+
#endif
|
776
|
+
case XML_HTML_DOCUMENT_NODE:
|
777
|
+
case XML_DTD_NODE:
|
778
|
+
node = rxn->node->last;
|
779
|
+
break;
|
780
|
+
case XML_ATTRIBUTE_NODE:
|
781
|
+
{
|
782
|
+
xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
|
783
|
+
node = attr->last;
|
784
|
+
}
|
785
|
+
default:
|
786
|
+
node = NULL;
|
787
|
+
break;
|
788
|
+
}
|
789
|
+
|
790
|
+
if (node == NULL)
|
791
|
+
return(Qnil);
|
792
|
+
else
|
793
|
+
return(ruby_xml_node_new2(cXMLNode, rxn->xd, node));
|
794
|
+
}
|
795
|
+
|
796
|
+
|
797
|
+
/*
|
798
|
+
* call-seq:
|
799
|
+
* node.last? => (true|false)
|
800
|
+
*
|
801
|
+
* Determine whether this node has a last child node.
|
802
|
+
*/
|
803
|
+
VALUE
|
804
|
+
ruby_xml_node_last_q(VALUE self) {
|
805
|
+
ruby_xml_node *rxn;
|
806
|
+
xmlNodePtr node;
|
807
|
+
|
808
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
809
|
+
|
810
|
+
switch (rxn->node->type) {
|
811
|
+
case XML_ELEMENT_NODE:
|
812
|
+
case XML_ENTITY_REF_NODE:
|
813
|
+
case XML_ENTITY_NODE:
|
814
|
+
case XML_PI_NODE:
|
815
|
+
case XML_COMMENT_NODE:
|
816
|
+
case XML_DOCUMENT_NODE:
|
817
|
+
#ifdef LIBXML_DOCB_ENABLED
|
818
|
+
case XML_DOCB_DOCUMENT_NODE:
|
819
|
+
#endif
|
820
|
+
case XML_HTML_DOCUMENT_NODE:
|
821
|
+
case XML_DTD_NODE:
|
822
|
+
node = rxn->node->last;
|
823
|
+
break;
|
824
|
+
case XML_ATTRIBUTE_NODE:
|
825
|
+
{
|
826
|
+
xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
|
827
|
+
node = attr->last;
|
828
|
+
}
|
829
|
+
default:
|
830
|
+
node = NULL;
|
831
|
+
break;
|
832
|
+
}
|
833
|
+
|
834
|
+
if (node == NULL)
|
835
|
+
return(Qfalse);
|
836
|
+
else
|
837
|
+
return(Qtrue);
|
838
|
+
}
|
839
|
+
|
840
|
+
|
841
|
+
/*
|
842
|
+
* call-seq:
|
843
|
+
* node.line_num => num
|
844
|
+
*
|
845
|
+
* Obtain the line number (in the XML document) that this
|
846
|
+
* node was read from. If +default_line_numbers+ is set
|
847
|
+
* false (the default), this method returns zero.
|
848
|
+
*/
|
849
|
+
VALUE
|
850
|
+
ruby_xml_node_line_num(VALUE self) {
|
851
|
+
ruby_xml_node *rxn;
|
852
|
+
long line_num;
|
853
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
854
|
+
|
855
|
+
if (!xmlLineNumbersDefaultValue)
|
856
|
+
rb_warn("Line numbers were not retained: use XML::Parser::default_line_numbers=true");
|
857
|
+
|
858
|
+
line_num = xmlGetLineNo(rxn->node);
|
859
|
+
if (line_num == -1)
|
860
|
+
return(Qnil);
|
861
|
+
else
|
862
|
+
return(INT2NUM((long)line_num));
|
863
|
+
}
|
864
|
+
|
865
|
+
|
866
|
+
/*
|
867
|
+
* call-seq:
|
868
|
+
* node.xlink? => (true|false)
|
869
|
+
*
|
870
|
+
* Determine whether this node is an xlink node.
|
871
|
+
*/
|
872
|
+
VALUE
|
873
|
+
ruby_xml_node_xlink_q(VALUE self) {
|
874
|
+
ruby_xml_node *node;
|
875
|
+
ruby_xml_document *doc;
|
876
|
+
xlinkType xlt;
|
877
|
+
|
878
|
+
Data_Get_Struct(self, ruby_xml_node, node);
|
879
|
+
Data_Get_Struct(node->xd, ruby_xml_document, doc);
|
880
|
+
xlt = xlinkIsLink(doc->doc, node->node);
|
881
|
+
|
882
|
+
if (xlt == XLINK_TYPE_NONE)
|
883
|
+
return(Qfalse);
|
884
|
+
else
|
885
|
+
return(Qtrue);
|
886
|
+
}
|
887
|
+
|
888
|
+
|
889
|
+
/*
|
890
|
+
* call-seq:
|
891
|
+
* node.xlink_type => num
|
892
|
+
*
|
893
|
+
* Obtain the type identifier for this xlink, if applicable.
|
894
|
+
* If this is not an xlink node (see +xlink?+), will return
|
895
|
+
* nil.
|
896
|
+
*/
|
897
|
+
VALUE
|
898
|
+
ruby_xml_node_xlink_type(VALUE self) {
|
899
|
+
ruby_xml_node *node;
|
900
|
+
ruby_xml_document *doc;
|
901
|
+
xlinkType xlt;
|
902
|
+
|
903
|
+
Data_Get_Struct(self, ruby_xml_node, node);
|
904
|
+
Data_Get_Struct(node->xd, ruby_xml_document, doc);
|
905
|
+
xlt = xlinkIsLink(doc->doc, node->node);
|
906
|
+
|
907
|
+
if (xlt == XLINK_TYPE_NONE)
|
908
|
+
return(Qnil);
|
909
|
+
else
|
910
|
+
return(INT2NUM(xlt));
|
911
|
+
}
|
912
|
+
|
913
|
+
|
914
|
+
/*
|
915
|
+
* call-seq:
|
916
|
+
* node.xlink_type_name => "string"
|
917
|
+
*
|
918
|
+
* Obtain the type name for this xlink, if applicable.
|
919
|
+
* If this is not an xlink node (see +xlink?+), will return
|
920
|
+
* nil.
|
921
|
+
*/
|
922
|
+
VALUE
|
923
|
+
ruby_xml_node_xlink_type_name(VALUE self) {
|
924
|
+
ruby_xml_node *node;
|
925
|
+
ruby_xml_document *doc;
|
926
|
+
xlinkType xlt;
|
927
|
+
|
928
|
+
Data_Get_Struct(self, ruby_xml_node, node);
|
929
|
+
Data_Get_Struct(node->xd, ruby_xml_document, doc);
|
930
|
+
xlt = xlinkIsLink(doc->doc, node->node);
|
931
|
+
|
932
|
+
switch(xlt) {
|
933
|
+
case XLINK_TYPE_NONE:
|
934
|
+
return(Qnil);
|
935
|
+
case XLINK_TYPE_SIMPLE:
|
936
|
+
return(rb_str_new2("simple"));
|
937
|
+
case XLINK_TYPE_EXTENDED:
|
938
|
+
return(rb_str_new2("extended"));
|
939
|
+
case XLINK_TYPE_EXTENDED_SET:
|
940
|
+
return(rb_str_new2("extended_set"));
|
941
|
+
default:
|
942
|
+
rb_fatal("Unknowng xlink type, %d", xlt);
|
943
|
+
}
|
944
|
+
}
|
945
|
+
|
946
|
+
|
947
|
+
static void
|
948
|
+
ruby_xml_node_mark(ruby_xml_node *rxn) {
|
949
|
+
if (rxn == NULL) return;
|
950
|
+
if (!NIL_P(rxn->xd)) rb_gc_mark(rxn->xd);
|
951
|
+
}
|
952
|
+
|
953
|
+
|
954
|
+
/*
|
955
|
+
* call-seq:
|
956
|
+
* node.name => "string"
|
957
|
+
*
|
958
|
+
* Obtain this node's name.
|
959
|
+
*/
|
960
|
+
VALUE
|
961
|
+
ruby_xml_node_name_get(VALUE self) {
|
962
|
+
ruby_xml_node *rxn;
|
963
|
+
const xmlChar *name;
|
964
|
+
|
965
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
966
|
+
|
967
|
+
switch (rxn->node->type) {
|
968
|
+
case XML_DOCUMENT_NODE:
|
969
|
+
#ifdef LIBXML_DOCB_ENABLED
|
970
|
+
case XML_DOCB_DOCUMENT_NODE:
|
971
|
+
#endif
|
972
|
+
case XML_HTML_DOCUMENT_NODE:
|
973
|
+
{
|
974
|
+
xmlDocPtr doc = (xmlDocPtr) rxn->node;
|
975
|
+
name = doc->URL;
|
976
|
+
break;
|
977
|
+
}
|
978
|
+
case XML_ATTRIBUTE_NODE:
|
979
|
+
{
|
980
|
+
xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
|
981
|
+
name = attr->name;
|
982
|
+
break;
|
983
|
+
}
|
984
|
+
case XML_NAMESPACE_DECL:
|
985
|
+
{
|
986
|
+
xmlNsPtr ns = (xmlNsPtr) rxn->node;
|
987
|
+
name = ns->prefix;
|
988
|
+
break;
|
989
|
+
}
|
990
|
+
default:
|
991
|
+
name = rxn->node->name;
|
992
|
+
break;
|
993
|
+
}
|
994
|
+
|
995
|
+
if (rxn->node->name == NULL)
|
996
|
+
return(Qnil);
|
997
|
+
else
|
998
|
+
return(rb_str_new2((const char*)name));
|
999
|
+
}
|
1000
|
+
|
1001
|
+
|
1002
|
+
/*
|
1003
|
+
* call-seq:
|
1004
|
+
* node.name = "string"
|
1005
|
+
*
|
1006
|
+
* Set this node's name.
|
1007
|
+
*/
|
1008
|
+
VALUE
|
1009
|
+
ruby_xml_node_name_set(VALUE self, VALUE name) {
|
1010
|
+
ruby_xml_node *node;
|
1011
|
+
|
1012
|
+
Check_Type(name, T_STRING);
|
1013
|
+
Data_Get_Struct(self, ruby_xml_node, node);
|
1014
|
+
xmlNodeSetName(node->node, (xmlChar*)StringValuePtr(name));
|
1015
|
+
return(Qtrue);
|
1016
|
+
}
|
1017
|
+
|
1018
|
+
|
1019
|
+
/*
|
1020
|
+
* call-seq:
|
1021
|
+
* node.namespace => [namespace, ..., namespace]
|
1022
|
+
*
|
1023
|
+
* Obtain an array of +XML::NS+ objects representing
|
1024
|
+
* this node's xmlns attributes
|
1025
|
+
*/
|
1026
|
+
VALUE
|
1027
|
+
ruby_xml_node_namespace_get(VALUE self) {
|
1028
|
+
ruby_xml_node *node;
|
1029
|
+
xmlNsPtr *nsList, *cur;
|
1030
|
+
VALUE arr, ns;
|
1031
|
+
|
1032
|
+
Data_Get_Struct(self, ruby_xml_node, node);
|
1033
|
+
if (node->node == NULL)
|
1034
|
+
return(Qnil);
|
1035
|
+
|
1036
|
+
nsList = xmlGetNsList(node->node->doc, node->node);
|
1037
|
+
|
1038
|
+
if (nsList == NULL)
|
1039
|
+
return(Qnil);
|
1040
|
+
|
1041
|
+
arr = rb_ary_new();
|
1042
|
+
for (cur = nsList; *cur != NULL; cur++) {
|
1043
|
+
ns = ruby_xml_ns_new2(cXMLNS, node->xd, *cur);
|
1044
|
+
if (ns == Qnil)
|
1045
|
+
continue;
|
1046
|
+
else
|
1047
|
+
rb_ary_push(arr, ns);
|
1048
|
+
}
|
1049
|
+
xmlFree(nsList);
|
1050
|
+
|
1051
|
+
return(arr);
|
1052
|
+
}
|
1053
|
+
|
1054
|
+
|
1055
|
+
/*
|
1056
|
+
* call-seq:
|
1057
|
+
* node.namespace_node => namespace.
|
1058
|
+
*
|
1059
|
+
* Obtain this node's namespace node.
|
1060
|
+
*/
|
1061
|
+
VALUE
|
1062
|
+
ruby_xml_node_namespace_get_node(VALUE self) {
|
1063
|
+
ruby_xml_node *node;
|
1064
|
+
|
1065
|
+
Data_Get_Struct(self, ruby_xml_node, node);
|
1066
|
+
if (node->node->ns == NULL)
|
1067
|
+
return(Qnil);
|
1068
|
+
else
|
1069
|
+
return(ruby_xml_ns_new2(cXMLNS, node->xd, node->node->ns));
|
1070
|
+
}
|
1071
|
+
|
1072
|
+
// TODO namespace_set can take varargs (in fact, must if used
|
1073
|
+
// with strings), but I cannot see how you can call
|
1074
|
+
// that version, apart from with 'send'
|
1075
|
+
//
|
1076
|
+
// Would sure be nice to support foo.namespace['foo'] = 'bar'
|
1077
|
+
// but maybe that's not practical...
|
1078
|
+
|
1079
|
+
/*
|
1080
|
+
* call-seq:
|
1081
|
+
* node.namespace = namespace
|
1082
|
+
*
|
1083
|
+
* Add the specified XML::NS object to this node's xmlns attributes.
|
1084
|
+
*/
|
1085
|
+
VALUE
|
1086
|
+
ruby_xml_node_namespace_set(int argc, VALUE *argv, VALUE self) {
|
1087
|
+
VALUE rns, rprefix;
|
1088
|
+
ruby_xml_node *rxn;
|
1089
|
+
ruby_xml_ns *rxns;
|
1090
|
+
xmlNsPtr ns;
|
1091
|
+
char *cp, *href;
|
1092
|
+
|
1093
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1094
|
+
switch (argc) {
|
1095
|
+
case 1:
|
1096
|
+
rns = argv[0];
|
1097
|
+
if (TYPE(rns) == T_STRING) {
|
1098
|
+
cp = strchr(StringValuePtr(rns), (int)':');
|
1099
|
+
if (cp == NULL) {
|
1100
|
+
rprefix = rns;
|
1101
|
+
href = NULL;
|
1102
|
+
} else {
|
1103
|
+
rprefix = rb_str_new(StringValuePtr(rns), (int)((long)cp - (long)StringValuePtr(rns)));
|
1104
|
+
href = &cp[1]; /* skip the : */
|
1105
|
+
}
|
1106
|
+
} else if (rb_obj_is_kind_of(rns, cXMLNS) == Qtrue) {
|
1107
|
+
Data_Get_Struct(self, ruby_xml_ns, rxns);
|
1108
|
+
xmlSetNs(rxn->node, rxns->ns);
|
1109
|
+
return(rns);
|
1110
|
+
} else
|
1111
|
+
rb_raise(rb_eTypeError, "must pass a string or an XML::Ns object");
|
1112
|
+
|
1113
|
+
/* Fall through to next case because when argc == 1, we need to
|
1114
|
+
* manually setup the additional args unless the arg passed is of
|
1115
|
+
* cXMLNS type */
|
1116
|
+
case 2:
|
1117
|
+
/* Don't want this code run in the fall through case */
|
1118
|
+
if (argc == 2) {
|
1119
|
+
rprefix = argv[0];
|
1120
|
+
href = StringValuePtr(argv[1]);
|
1121
|
+
}
|
1122
|
+
|
1123
|
+
ns = xmlNewNs(rxn->node, (xmlChar*)href, (xmlChar*)StringValuePtr(rprefix));
|
1124
|
+
if (ns == NULL)
|
1125
|
+
rb_raise(eXMLNodeSetNamespace, "unable to set the namespace");
|
1126
|
+
else
|
1127
|
+
return(ruby_xml_ns_new2(cXMLNS, rxn->xd, ns));
|
1128
|
+
break;
|
1129
|
+
|
1130
|
+
default:
|
1131
|
+
rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
|
1132
|
+
}
|
1133
|
+
|
1134
|
+
/* can't get here */
|
1135
|
+
return(Qnil);
|
1136
|
+
}
|
1137
|
+
|
1138
|
+
|
1139
|
+
/*
|
1140
|
+
* call-seq:
|
1141
|
+
* node.namespace? => (true|false)
|
1142
|
+
*
|
1143
|
+
* Determine whether this node *is* (not has) a namespace
|
1144
|
+
* node.
|
1145
|
+
*/
|
1146
|
+
VALUE
|
1147
|
+
ruby_xml_node_namespace_q(VALUE self) {
|
1148
|
+
ruby_xml_node *rxn;
|
1149
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1150
|
+
if (rxn->node->type == XML_NAMESPACE_DECL)
|
1151
|
+
return(Qtrue);
|
1152
|
+
else
|
1153
|
+
return(Qfalse);
|
1154
|
+
}
|
1155
|
+
|
1156
|
+
|
1157
|
+
VALUE
|
1158
|
+
ruby_xml_node_new(VALUE class, xmlNodePtr node) {
|
1159
|
+
ruby_xml_node *rxn;
|
1160
|
+
|
1161
|
+
rxn = ALLOC(ruby_xml_node);
|
1162
|
+
rxn->is_ptr = 0;
|
1163
|
+
rxn->node = node;
|
1164
|
+
rxn->xd = Qnil;
|
1165
|
+
return(Data_Wrap_Struct(class, ruby_xml_node_mark,
|
1166
|
+
ruby_xml_node_free, rxn));
|
1167
|
+
}
|
1168
|
+
|
1169
|
+
|
1170
|
+
VALUE
|
1171
|
+
ruby_xml_node_new2(VALUE class, VALUE xd, xmlNodePtr node) {
|
1172
|
+
ruby_xml_node *rxn;
|
1173
|
+
|
1174
|
+
rxn = ALLOC(ruby_xml_node);
|
1175
|
+
rxn->is_ptr = 1;
|
1176
|
+
rxn->node = node;
|
1177
|
+
if (NIL_P(xd))
|
1178
|
+
rxn->xd = Qnil;
|
1179
|
+
else
|
1180
|
+
rxn->xd = xd;
|
1181
|
+
return(Data_Wrap_Struct(class, ruby_xml_node_mark,
|
1182
|
+
ruby_xml_node_free, rxn));
|
1183
|
+
}
|
1184
|
+
|
1185
|
+
|
1186
|
+
/*
|
1187
|
+
* call-seq:
|
1188
|
+
* node.next => node
|
1189
|
+
*
|
1190
|
+
* Obtain the next sibling node, if any.
|
1191
|
+
*/
|
1192
|
+
VALUE
|
1193
|
+
ruby_xml_node_next_get(VALUE self) {
|
1194
|
+
ruby_xml_node *rxn;
|
1195
|
+
xmlNodePtr node;
|
1196
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1197
|
+
|
1198
|
+
switch (rxn->node->type) {
|
1199
|
+
case XML_DOCUMENT_NODE:
|
1200
|
+
#ifdef LIBXML_DOCB_ENABLED
|
1201
|
+
case XML_DOCB_DOCUMENT_NODE:
|
1202
|
+
#endif
|
1203
|
+
case XML_HTML_DOCUMENT_NODE:
|
1204
|
+
node = NULL;
|
1205
|
+
break;
|
1206
|
+
case XML_ATTRIBUTE_NODE:
|
1207
|
+
{
|
1208
|
+
xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
|
1209
|
+
node = (xmlNodePtr) attr->next;
|
1210
|
+
break;
|
1211
|
+
}
|
1212
|
+
case XML_NAMESPACE_DECL:
|
1213
|
+
{
|
1214
|
+
xmlNsPtr ns = (xmlNsPtr) rxn->node;
|
1215
|
+
node = (xmlNodePtr) ns->next;
|
1216
|
+
break;
|
1217
|
+
}
|
1218
|
+
default:
|
1219
|
+
node = rxn->node->next;
|
1220
|
+
break;
|
1221
|
+
}
|
1222
|
+
|
1223
|
+
if (node == NULL)
|
1224
|
+
return(Qnil);
|
1225
|
+
else
|
1226
|
+
return(ruby_xml_node_new2(cXMLNode, rxn->xd, node));
|
1227
|
+
}
|
1228
|
+
|
1229
|
+
|
1230
|
+
/*
|
1231
|
+
* call-seq:
|
1232
|
+
* node.next? => (true|false)
|
1233
|
+
*
|
1234
|
+
* Determine whether this node has a next sibling.
|
1235
|
+
*/
|
1236
|
+
VALUE
|
1237
|
+
ruby_xml_node_next_q(VALUE self) {
|
1238
|
+
ruby_xml_node *rxn;
|
1239
|
+
xmlNodePtr node;
|
1240
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1241
|
+
|
1242
|
+
switch (rxn->node->type) {
|
1243
|
+
case XML_DOCUMENT_NODE:
|
1244
|
+
#ifdef LIBXML_DOCB_ENABLED
|
1245
|
+
case XML_DOCB_DOCUMENT_NODE:
|
1246
|
+
#endif
|
1247
|
+
case XML_HTML_DOCUMENT_NODE:
|
1248
|
+
node = NULL;
|
1249
|
+
break;
|
1250
|
+
case XML_ATTRIBUTE_NODE:
|
1251
|
+
{
|
1252
|
+
xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
|
1253
|
+
node = (xmlNodePtr) attr->next;
|
1254
|
+
break;
|
1255
|
+
}
|
1256
|
+
case XML_NAMESPACE_DECL:
|
1257
|
+
{
|
1258
|
+
xmlNsPtr ns = (xmlNsPtr) rxn->node;
|
1259
|
+
node = (xmlNodePtr) ns->next;
|
1260
|
+
break;
|
1261
|
+
}
|
1262
|
+
default:
|
1263
|
+
node = rxn->node->next;
|
1264
|
+
break;
|
1265
|
+
}
|
1266
|
+
|
1267
|
+
if (node == NULL)
|
1268
|
+
return(Qfalse);
|
1269
|
+
else
|
1270
|
+
return(Qtrue);
|
1271
|
+
}
|
1272
|
+
|
1273
|
+
|
1274
|
+
/*
|
1275
|
+
* call-seq:
|
1276
|
+
* node.notation? => (true|false)
|
1277
|
+
*
|
1278
|
+
* Determine whether this is a notation node
|
1279
|
+
*/
|
1280
|
+
VALUE
|
1281
|
+
ruby_xml_node_notation_q(VALUE self) {
|
1282
|
+
ruby_xml_node *rxn;
|
1283
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1284
|
+
if (rxn->node->type == XML_NOTATION_NODE)
|
1285
|
+
return(Qtrue);
|
1286
|
+
else
|
1287
|
+
return(Qfalse);
|
1288
|
+
}
|
1289
|
+
|
1290
|
+
|
1291
|
+
/*
|
1292
|
+
* call-seq:
|
1293
|
+
* node.ns? => (true|false)
|
1294
|
+
*
|
1295
|
+
* Determine whether this node is a namespace node.
|
1296
|
+
*/
|
1297
|
+
VALUE
|
1298
|
+
ruby_xml_node_ns_q(VALUE self) {
|
1299
|
+
ruby_xml_node *rxn;
|
1300
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1301
|
+
if (rxn->node->ns == NULL)
|
1302
|
+
return(Qfalse);
|
1303
|
+
else
|
1304
|
+
return(Qtrue);
|
1305
|
+
}
|
1306
|
+
|
1307
|
+
|
1308
|
+
/*
|
1309
|
+
* call-seq:
|
1310
|
+
* node.ns_def => namespace
|
1311
|
+
*
|
1312
|
+
* Obtain this node's default namespace.
|
1313
|
+
*/
|
1314
|
+
VALUE
|
1315
|
+
ruby_xml_node_ns_def_get(VALUE self) {
|
1316
|
+
ruby_xml_node *rxn;
|
1317
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1318
|
+
if (rxn->node->nsDef == NULL)
|
1319
|
+
return(Qnil);
|
1320
|
+
else
|
1321
|
+
return(ruby_xml_ns_new2(cXMLNS, rxn->xd, rxn->node->nsDef));
|
1322
|
+
}
|
1323
|
+
|
1324
|
+
|
1325
|
+
/*
|
1326
|
+
* call-seq:
|
1327
|
+
* node.ns_def? => (true|false)
|
1328
|
+
*
|
1329
|
+
* Obtain an array of +XML::NS+ objects representing
|
1330
|
+
* this node's xmlns attributes
|
1331
|
+
*/
|
1332
|
+
VALUE
|
1333
|
+
ruby_xml_node_ns_def_q(VALUE self) {
|
1334
|
+
ruby_xml_node *rxn;
|
1335
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1336
|
+
if (rxn->node->nsDef == NULL)
|
1337
|
+
return(Qfalse);
|
1338
|
+
else
|
1339
|
+
return(Qtrue);
|
1340
|
+
}
|
1341
|
+
|
1342
|
+
|
1343
|
+
/*
|
1344
|
+
* call-seq:
|
1345
|
+
* node.parent => node
|
1346
|
+
*
|
1347
|
+
* Obtain this node's parent node, if any.
|
1348
|
+
*/
|
1349
|
+
VALUE
|
1350
|
+
ruby_xml_node_parent_get(VALUE self) {
|
1351
|
+
ruby_xml_node *rxn;
|
1352
|
+
xmlNodePtr node;
|
1353
|
+
|
1354
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1355
|
+
|
1356
|
+
switch (rxn->node->type) {
|
1357
|
+
case XML_DOCUMENT_NODE:
|
1358
|
+
case XML_HTML_DOCUMENT_NODE:
|
1359
|
+
#ifdef LIBXML_DOCB_ENABLED
|
1360
|
+
case XML_DOCB_DOCUMENT_NODE:
|
1361
|
+
#endif
|
1362
|
+
node = NULL;
|
1363
|
+
break;
|
1364
|
+
case XML_ATTRIBUTE_NODE:
|
1365
|
+
{
|
1366
|
+
xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
|
1367
|
+
node = attr->parent;
|
1368
|
+
}
|
1369
|
+
case XML_ENTITY_DECL:
|
1370
|
+
case XML_NAMESPACE_DECL:
|
1371
|
+
case XML_XINCLUDE_START:
|
1372
|
+
case XML_XINCLUDE_END:
|
1373
|
+
node = NULL;
|
1374
|
+
break;
|
1375
|
+
default:
|
1376
|
+
node = rxn->node->parent;
|
1377
|
+
break;
|
1378
|
+
}
|
1379
|
+
|
1380
|
+
if (node == NULL)
|
1381
|
+
return(Qnil);
|
1382
|
+
else
|
1383
|
+
return(ruby_xml_node_new2(cXMLNode, rxn->xd, node));
|
1384
|
+
}
|
1385
|
+
|
1386
|
+
|
1387
|
+
/*
|
1388
|
+
* call-seq:
|
1389
|
+
* node.parent? => (true|false)
|
1390
|
+
*
|
1391
|
+
* Determine whether this node has a parent node.
|
1392
|
+
*/
|
1393
|
+
VALUE
|
1394
|
+
ruby_xml_node_parent_q(VALUE self) {
|
1395
|
+
ruby_xml_node *rxn;
|
1396
|
+
xmlNodePtr node;
|
1397
|
+
|
1398
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1399
|
+
|
1400
|
+
switch (rxn->node->type) {
|
1401
|
+
case XML_DOCUMENT_NODE:
|
1402
|
+
case XML_HTML_DOCUMENT_NODE:
|
1403
|
+
#ifdef LIBXML_DOCB_ENABLED
|
1404
|
+
case XML_DOCB_DOCUMENT_NODE:
|
1405
|
+
#endif
|
1406
|
+
node = NULL;
|
1407
|
+
break;
|
1408
|
+
case XML_ATTRIBUTE_NODE:
|
1409
|
+
{
|
1410
|
+
xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
|
1411
|
+
node = attr->parent;
|
1412
|
+
}
|
1413
|
+
case XML_ENTITY_DECL:
|
1414
|
+
case XML_NAMESPACE_DECL:
|
1415
|
+
case XML_XINCLUDE_START:
|
1416
|
+
case XML_XINCLUDE_END:
|
1417
|
+
node = NULL;
|
1418
|
+
break;
|
1419
|
+
default:
|
1420
|
+
node = rxn->node->parent;
|
1421
|
+
break;
|
1422
|
+
}
|
1423
|
+
|
1424
|
+
if (node == NULL)
|
1425
|
+
return(Qfalse);
|
1426
|
+
else
|
1427
|
+
return(Qtrue);
|
1428
|
+
}
|
1429
|
+
|
1430
|
+
|
1431
|
+
/*
|
1432
|
+
* call-seq:
|
1433
|
+
* node.path => path
|
1434
|
+
*
|
1435
|
+
* Obtain this node's path.
|
1436
|
+
*/
|
1437
|
+
VALUE
|
1438
|
+
ruby_xml_node_path(VALUE self) {
|
1439
|
+
ruby_xml_node *rxn;
|
1440
|
+
xmlChar *path;
|
1441
|
+
|
1442
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1443
|
+
path = xmlGetNodePath(rxn->node);
|
1444
|
+
|
1445
|
+
if (path == NULL)
|
1446
|
+
return(Qnil);
|
1447
|
+
else
|
1448
|
+
return(rb_str_new2((const char*)path));
|
1449
|
+
}
|
1450
|
+
|
1451
|
+
|
1452
|
+
/*
|
1453
|
+
* call-seq:
|
1454
|
+
* node.pi? => (true|false)
|
1455
|
+
*
|
1456
|
+
* Determine whether this is a processing instruction node.
|
1457
|
+
*/
|
1458
|
+
VALUE
|
1459
|
+
ruby_xml_node_pi_q(VALUE self) {
|
1460
|
+
ruby_xml_node *rxn;
|
1461
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1462
|
+
if (rxn->node->type == XML_PI_NODE)
|
1463
|
+
return(Qtrue);
|
1464
|
+
else
|
1465
|
+
return(Qfalse);
|
1466
|
+
}
|
1467
|
+
|
1468
|
+
|
1469
|
+
/*
|
1470
|
+
* call-seq:
|
1471
|
+
* node.pointer => node_set
|
1472
|
+
*
|
1473
|
+
* Evaluates an XPointer expression relative to this node.
|
1474
|
+
*/
|
1475
|
+
VALUE
|
1476
|
+
ruby_xml_node_pointer(VALUE self, VALUE xptr_str) {
|
1477
|
+
return(ruby_xml_xpointer_point2(self, xptr_str));
|
1478
|
+
}
|
1479
|
+
|
1480
|
+
|
1481
|
+
/*
|
1482
|
+
* call-seq:
|
1483
|
+
* node.prev => node
|
1484
|
+
*
|
1485
|
+
* Obtain the previous sibling, if any.
|
1486
|
+
*/
|
1487
|
+
VALUE
|
1488
|
+
ruby_xml_node_prev_get(VALUE self) {
|
1489
|
+
ruby_xml_node *rxn;
|
1490
|
+
xmlNodePtr node;
|
1491
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1492
|
+
|
1493
|
+
switch (rxn->node->type) {
|
1494
|
+
case XML_DOCUMENT_NODE:
|
1495
|
+
#ifdef LIBXML_DOCB_ENABLED
|
1496
|
+
case XML_DOCB_DOCUMENT_NODE:
|
1497
|
+
#endif
|
1498
|
+
case XML_HTML_DOCUMENT_NODE:
|
1499
|
+
case XML_NAMESPACE_DECL:
|
1500
|
+
node = NULL;
|
1501
|
+
break;
|
1502
|
+
case XML_ATTRIBUTE_NODE:
|
1503
|
+
{
|
1504
|
+
xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
|
1505
|
+
node = (xmlNodePtr) attr->next;
|
1506
|
+
}
|
1507
|
+
break;
|
1508
|
+
default:
|
1509
|
+
node = rxn->node->next;
|
1510
|
+
break;
|
1511
|
+
}
|
1512
|
+
|
1513
|
+
if (node == NULL)
|
1514
|
+
return(Qnil);
|
1515
|
+
else
|
1516
|
+
return(ruby_xml_node_new2(cXMLNode, rxn->xd, node));
|
1517
|
+
}
|
1518
|
+
|
1519
|
+
|
1520
|
+
/*
|
1521
|
+
* call-seq:
|
1522
|
+
* node.prev? => (true|false)
|
1523
|
+
*
|
1524
|
+
* Determines whether this node has a previous sibling node.
|
1525
|
+
*/
|
1526
|
+
VALUE
|
1527
|
+
ruby_xml_node_prev_q(VALUE self) {
|
1528
|
+
ruby_xml_node *rxn;
|
1529
|
+
xmlNodePtr node;
|
1530
|
+
|
1531
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1532
|
+
|
1533
|
+
switch (rxn->node->type) {
|
1534
|
+
case XML_DOCUMENT_NODE:
|
1535
|
+
#ifdef LIBXML_DOCB_ENABLED
|
1536
|
+
case XML_DOCB_DOCUMENT_NODE:
|
1537
|
+
#endif
|
1538
|
+
case XML_HTML_DOCUMENT_NODE:
|
1539
|
+
case XML_NAMESPACE_DECL:
|
1540
|
+
node = NULL;
|
1541
|
+
break;
|
1542
|
+
case XML_ATTRIBUTE_NODE:
|
1543
|
+
{
|
1544
|
+
xmlAttrPtr attr = (xmlAttrPtr) rxn->node;
|
1545
|
+
node = (xmlNodePtr) attr->next;
|
1546
|
+
}
|
1547
|
+
break;
|
1548
|
+
default:
|
1549
|
+
node = rxn->node->next;
|
1550
|
+
break;
|
1551
|
+
}
|
1552
|
+
|
1553
|
+
if (node == NULL)
|
1554
|
+
return(Qfalse);
|
1555
|
+
else
|
1556
|
+
return(Qtrue);
|
1557
|
+
}
|
1558
|
+
|
1559
|
+
|
1560
|
+
/*
|
1561
|
+
* call-seq:
|
1562
|
+
* node.property("name") => "string"
|
1563
|
+
* node["name"] => "string"
|
1564
|
+
*
|
1565
|
+
* Obtain the named property.
|
1566
|
+
*/
|
1567
|
+
VALUE
|
1568
|
+
ruby_xml_node_property_get(VALUE self, VALUE prop) {
|
1569
|
+
ruby_xml_node *rxn;
|
1570
|
+
xmlChar *p;
|
1571
|
+
VALUE r;
|
1572
|
+
|
1573
|
+
Check_Type(prop, T_STRING);
|
1574
|
+
|
1575
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1576
|
+
p = xmlGetProp(rxn->node, (xmlChar*)StringValuePtr(prop));
|
1577
|
+
|
1578
|
+
if (p == NULL)
|
1579
|
+
r = Qnil;
|
1580
|
+
else {
|
1581
|
+
r = rb_str_new2((const char*)p);
|
1582
|
+
xmlFree(p);
|
1583
|
+
}
|
1584
|
+
|
1585
|
+
return r;
|
1586
|
+
}
|
1587
|
+
|
1588
|
+
|
1589
|
+
/*
|
1590
|
+
* call-seq:
|
1591
|
+
* node["name"] = "string"
|
1592
|
+
*
|
1593
|
+
* Set the named property.
|
1594
|
+
*/
|
1595
|
+
VALUE
|
1596
|
+
ruby_xml_node_property_set(VALUE self, VALUE key, VALUE val) {
|
1597
|
+
ruby_xml_node *node;
|
1598
|
+
ruby_xml_attr *rxa;
|
1599
|
+
xmlAttrPtr attr;
|
1600
|
+
VALUE rattr;
|
1601
|
+
|
1602
|
+
Check_Type(key, T_STRING);
|
1603
|
+
Check_Type(val, T_STRING);
|
1604
|
+
Data_Get_Struct(self, ruby_xml_node, node);
|
1605
|
+
|
1606
|
+
attr = xmlSetProp(node->node, (xmlChar*)StringValuePtr(key), (xmlChar*)StringValuePtr(val));
|
1607
|
+
if (attr == NULL) {
|
1608
|
+
attr = xmlNewProp(node->node, (xmlChar*)StringValuePtr(key), (xmlChar*)StringValuePtr(val));
|
1609
|
+
if (attr == NULL)
|
1610
|
+
return(Qnil);
|
1611
|
+
}
|
1612
|
+
rattr = ruby_xml_attr_new(cXMLAttr, node->xd, attr);
|
1613
|
+
Data_Get_Struct(rattr, ruby_xml_attr, rxa);
|
1614
|
+
rxa->is_ptr = 1;
|
1615
|
+
return(rattr);
|
1616
|
+
}
|
1617
|
+
|
1618
|
+
|
1619
|
+
/*
|
1620
|
+
* call-seq:
|
1621
|
+
* node.properties => attributes
|
1622
|
+
*
|
1623
|
+
* Returns the +XML::Attr+ for this node.
|
1624
|
+
*/
|
1625
|
+
VALUE
|
1626
|
+
ruby_xml_node_properties_get(VALUE self) {
|
1627
|
+
ruby_xml_node *node;
|
1628
|
+
xmlAttrPtr attr;
|
1629
|
+
|
1630
|
+
Data_Get_Struct(self, ruby_xml_node, node);
|
1631
|
+
|
1632
|
+
if (node->node->type == XML_ELEMENT_NODE) {
|
1633
|
+
attr = node->node->properties;
|
1634
|
+
return(ruby_xml_attr_new2(cXMLAttr, node->xd, attr));
|
1635
|
+
} else {
|
1636
|
+
return(Qnil);
|
1637
|
+
}
|
1638
|
+
}
|
1639
|
+
|
1640
|
+
|
1641
|
+
/*
|
1642
|
+
* call-seq:
|
1643
|
+
* node.properties? => (true|false)
|
1644
|
+
*
|
1645
|
+
* Determine whether this node has properties
|
1646
|
+
* (attributes).
|
1647
|
+
*/
|
1648
|
+
VALUE
|
1649
|
+
ruby_xml_node_properties_q(VALUE self) {
|
1650
|
+
ruby_xml_node *rxn;
|
1651
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1652
|
+
if (rxn->node->type == XML_ELEMENT_NODE && rxn->node->properties != NULL)
|
1653
|
+
return(Qtrue);
|
1654
|
+
else
|
1655
|
+
return(Qfalse);
|
1656
|
+
}
|
1657
|
+
|
1658
|
+
|
1659
|
+
/*
|
1660
|
+
* call-seq:
|
1661
|
+
* node.search_href => namespace
|
1662
|
+
*
|
1663
|
+
* Search for a namespace by href.
|
1664
|
+
*/
|
1665
|
+
VALUE
|
1666
|
+
ruby_xml_node_search_href(VALUE self, VALUE href) {
|
1667
|
+
ruby_xml_document *doc;
|
1668
|
+
ruby_xml_node *node;
|
1669
|
+
|
1670
|
+
Check_Type(href, T_STRING);
|
1671
|
+
Data_Get_Struct(self, ruby_xml_node, node);
|
1672
|
+
Data_Get_Struct(node->xd, ruby_xml_document, doc);
|
1673
|
+
return(ruby_xml_ns_new2(cXMLNS, node->xd,
|
1674
|
+
xmlSearchNsByHref(doc->doc, node->node,
|
1675
|
+
(xmlChar*)StringValuePtr(href))));
|
1676
|
+
}
|
1677
|
+
|
1678
|
+
|
1679
|
+
/*
|
1680
|
+
* call-seq:
|
1681
|
+
* node.search_ns => namespace
|
1682
|
+
*
|
1683
|
+
* Search for a namespace by namespace.
|
1684
|
+
*/
|
1685
|
+
VALUE
|
1686
|
+
ruby_xml_node_search_ns(VALUE self, VALUE ns) {
|
1687
|
+
ruby_xml_document *doc;
|
1688
|
+
ruby_xml_node *node;
|
1689
|
+
|
1690
|
+
Check_Type(ns, T_STRING);
|
1691
|
+
Data_Get_Struct(self, ruby_xml_node, node);
|
1692
|
+
Data_Get_Struct(node->xd, ruby_xml_document, doc);
|
1693
|
+
return(ruby_xml_ns_new2(cXMLNS, node->xd,
|
1694
|
+
xmlSearchNs(doc->doc, node->node,
|
1695
|
+
(xmlChar*)StringValuePtr(ns))));
|
1696
|
+
}
|
1697
|
+
|
1698
|
+
|
1699
|
+
VALUE
|
1700
|
+
ruby_xml_node_set_ptr(VALUE node, int is_ptr) {
|
1701
|
+
ruby_xml_node *rxn;
|
1702
|
+
Data_Get_Struct(node, ruby_xml_node, rxn);
|
1703
|
+
rxn->is_ptr = is_ptr;
|
1704
|
+
return(Qtrue);
|
1705
|
+
}
|
1706
|
+
|
1707
|
+
|
1708
|
+
/*
|
1709
|
+
* call-seq:
|
1710
|
+
* node.sibling(node) => node
|
1711
|
+
*
|
1712
|
+
* Add the specified node as a sibling of this node.
|
1713
|
+
*/
|
1714
|
+
VALUE
|
1715
|
+
ruby_xml_node_sibling_set(VALUE self, VALUE rnode) {
|
1716
|
+
ruby_xml_node *cnode, *pnode;
|
1717
|
+
xmlNodePtr ret;
|
1718
|
+
|
1719
|
+
if (rb_obj_is_kind_of(rnode, cXMLNode) == Qfalse)
|
1720
|
+
rb_raise(rb_eTypeError, "Must pass an XML::Node object");
|
1721
|
+
|
1722
|
+
Data_Get_Struct(self, ruby_xml_node, pnode);
|
1723
|
+
Data_Get_Struct(rnode, ruby_xml_node, cnode);
|
1724
|
+
|
1725
|
+
ret = xmlAddSibling(pnode->node, cnode->node);
|
1726
|
+
if (ret == NULL)
|
1727
|
+
rb_raise(eXMLNodeFailedModify, "unable to add a sibling to the document");
|
1728
|
+
|
1729
|
+
cnode->is_ptr = 1;
|
1730
|
+
return(ruby_xml_node_new2(cXMLNode, pnode->xd, ret));
|
1731
|
+
}
|
1732
|
+
|
1733
|
+
|
1734
|
+
/*
|
1735
|
+
* call-seq:
|
1736
|
+
* node.space_preserve => (true|false)
|
1737
|
+
*
|
1738
|
+
* Determine whether this node preserves whitespace.
|
1739
|
+
*/
|
1740
|
+
VALUE
|
1741
|
+
ruby_xml_node_space_preserve_get(VALUE self) {
|
1742
|
+
ruby_xml_node *rxn;
|
1743
|
+
|
1744
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1745
|
+
return(INT2NUM(xmlNodeGetSpacePreserve(rxn->node)));
|
1746
|
+
}
|
1747
|
+
|
1748
|
+
|
1749
|
+
/*
|
1750
|
+
* call-seq:
|
1751
|
+
* node.space_preserve = true|false
|
1752
|
+
*
|
1753
|
+
* Control whether this node preserves whitespace.
|
1754
|
+
*/
|
1755
|
+
VALUE
|
1756
|
+
ruby_xml_node_space_preserve_set(VALUE self, VALUE bool) {
|
1757
|
+
ruby_xml_node *rxn;
|
1758
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1759
|
+
|
1760
|
+
if (TYPE(bool) == T_FALSE)
|
1761
|
+
xmlNodeSetSpacePreserve(rxn->node, 1);
|
1762
|
+
else
|
1763
|
+
xmlNodeSetSpacePreserve(rxn->node, 0);
|
1764
|
+
|
1765
|
+
return(Qnil);
|
1766
|
+
}
|
1767
|
+
|
1768
|
+
|
1769
|
+
/*
|
1770
|
+
* call-seq:
|
1771
|
+
* node.text? => (true|false)
|
1772
|
+
*
|
1773
|
+
* Determine whether this node has text.
|
1774
|
+
*/
|
1775
|
+
VALUE
|
1776
|
+
ruby_xml_node_text_q(VALUE self) {
|
1777
|
+
ruby_xml_node *rxn;
|
1778
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1779
|
+
if (rxn->node == NULL)
|
1780
|
+
return(Qnil);
|
1781
|
+
|
1782
|
+
return((xmlNodeIsText(rxn->node) == 1) ? Qtrue : Qfalse);
|
1783
|
+
}
|
1784
|
+
|
1785
|
+
|
1786
|
+
/*
|
1787
|
+
* call-seq:
|
1788
|
+
* node.to_s => "string"
|
1789
|
+
*
|
1790
|
+
* Coerce this node to a string representation of
|
1791
|
+
* it's XML.
|
1792
|
+
*/
|
1793
|
+
VALUE
|
1794
|
+
ruby_xml_node_to_s(VALUE self) {
|
1795
|
+
ruby_xml_node *rxn;
|
1796
|
+
xmlBufferPtr buf;
|
1797
|
+
VALUE result;
|
1798
|
+
|
1799
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1800
|
+
buf = xmlBufferCreate();
|
1801
|
+
xmlNodeDump(buf, rxn->node->doc, rxn->node, 0, 1);
|
1802
|
+
result = rb_str_new2((const char*)buf->content);
|
1803
|
+
// TODO result = rb_str_new2((const char*)buf->content); ?
|
1804
|
+
|
1805
|
+
xmlBufferFree(buf);
|
1806
|
+
return result;
|
1807
|
+
}
|
1808
|
+
|
1809
|
+
|
1810
|
+
/*
|
1811
|
+
* call-seq:
|
1812
|
+
* node.type => num
|
1813
|
+
*
|
1814
|
+
* Obtain this node's type identifier.
|
1815
|
+
*/
|
1816
|
+
VALUE
|
1817
|
+
ruby_xml_node_type(VALUE self) {
|
1818
|
+
ruby_xml_node *rxn;
|
1819
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1820
|
+
return(INT2NUM(rxn->node->type));
|
1821
|
+
}
|
1822
|
+
|
1823
|
+
|
1824
|
+
/*
|
1825
|
+
* call-seq:
|
1826
|
+
* node.type_name => num
|
1827
|
+
*
|
1828
|
+
* Obtain this node's type name.
|
1829
|
+
*/
|
1830
|
+
VALUE
|
1831
|
+
ruby_xml_node_type_name(VALUE self) {
|
1832
|
+
ruby_xml_node *rxn;
|
1833
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1834
|
+
|
1835
|
+
switch(rxn->node->type) {
|
1836
|
+
case XML_ELEMENT_NODE:
|
1837
|
+
return(rb_str_new2("element"));
|
1838
|
+
case XML_ATTRIBUTE_NODE:
|
1839
|
+
return(rb_str_new2("attribute"));
|
1840
|
+
case XML_TEXT_NODE:
|
1841
|
+
return(rb_str_new2("text"));
|
1842
|
+
case XML_CDATA_SECTION_NODE:
|
1843
|
+
return(rb_str_new2("cdata"));
|
1844
|
+
case XML_ENTITY_REF_NODE:
|
1845
|
+
return(rb_str_new2("entity_ref"));
|
1846
|
+
case XML_ENTITY_NODE:
|
1847
|
+
return(rb_str_new2("entity"));
|
1848
|
+
case XML_PI_NODE:
|
1849
|
+
return(rb_str_new2("pi"));
|
1850
|
+
case XML_COMMENT_NODE:
|
1851
|
+
return(rb_str_new2("comment"));
|
1852
|
+
case XML_DOCUMENT_NODE:
|
1853
|
+
return(rb_str_new2("document_xml"));
|
1854
|
+
case XML_DOCUMENT_TYPE_NODE:
|
1855
|
+
return(rb_str_new2("doctype"));
|
1856
|
+
case XML_DOCUMENT_FRAG_NODE:
|
1857
|
+
return(rb_str_new2("fragment"));
|
1858
|
+
case XML_NOTATION_NODE:
|
1859
|
+
return(rb_str_new2("notation"));
|
1860
|
+
case XML_HTML_DOCUMENT_NODE:
|
1861
|
+
return(rb_str_new2("document_html"));
|
1862
|
+
case XML_DTD_NODE:
|
1863
|
+
return(rb_str_new2("dtd"));
|
1864
|
+
case XML_ELEMENT_DECL:
|
1865
|
+
return(rb_str_new2("elem_decl"));
|
1866
|
+
case XML_ATTRIBUTE_DECL:
|
1867
|
+
return(rb_str_new2("attribute_decl"));
|
1868
|
+
case XML_ENTITY_DECL:
|
1869
|
+
return(rb_str_new2("entity_decl"));
|
1870
|
+
case XML_NAMESPACE_DECL:
|
1871
|
+
return(rb_str_new2("namespace"));
|
1872
|
+
case XML_XINCLUDE_START:
|
1873
|
+
return(rb_str_new2("xinclude_start"));
|
1874
|
+
case XML_XINCLUDE_END:
|
1875
|
+
return(rb_str_new2("xinclude_end"));
|
1876
|
+
#ifdef LIBXML_DOCB_ENABLED
|
1877
|
+
case XML_DOCB_DOCUMENT_NODE:
|
1878
|
+
return(rb_str_new2("document_docbook"));
|
1879
|
+
#endif
|
1880
|
+
default:
|
1881
|
+
rb_raise(eXMLNodeUnknownType, "Unknown node type: %n", rxn->node->type);
|
1882
|
+
return(Qfalse);
|
1883
|
+
}
|
1884
|
+
}
|
1885
|
+
|
1886
|
+
|
1887
|
+
/*
|
1888
|
+
* call-seq:
|
1889
|
+
* node.xinclude_end? => num
|
1890
|
+
*
|
1891
|
+
* Determine whether this node is an xinclude end node.
|
1892
|
+
*/
|
1893
|
+
VALUE
|
1894
|
+
ruby_xml_node_xinclude_end_q(VALUE self) {
|
1895
|
+
ruby_xml_node *rxn;
|
1896
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1897
|
+
if (rxn->node->type == XML_XINCLUDE_END)
|
1898
|
+
return(Qtrue);
|
1899
|
+
else
|
1900
|
+
return(Qfalse);
|
1901
|
+
}
|
1902
|
+
|
1903
|
+
|
1904
|
+
/*
|
1905
|
+
* call-seq:
|
1906
|
+
* node.xinclude_start? => num
|
1907
|
+
*
|
1908
|
+
* Determine whether this node is an xinclude start node.
|
1909
|
+
*/
|
1910
|
+
VALUE
|
1911
|
+
ruby_xml_node_xinclude_start_q(VALUE self) {
|
1912
|
+
ruby_xml_node *rxn;
|
1913
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1914
|
+
if (rxn->node->type == XML_XINCLUDE_START)
|
1915
|
+
return(Qtrue);
|
1916
|
+
else
|
1917
|
+
return(Qfalse);
|
1918
|
+
}
|
1919
|
+
|
1920
|
+
|
1921
|
+
// TODO my gut tells me this is where our sigseg etc. problems start...
|
1922
|
+
|
1923
|
+
/*
|
1924
|
+
* call-seq:
|
1925
|
+
* node.copy => node
|
1926
|
+
*
|
1927
|
+
* Create a copy of this node.
|
1928
|
+
*/
|
1929
|
+
VALUE
|
1930
|
+
ruby_xml_node_copy(VALUE self, VALUE deep) { /* MUFF */
|
1931
|
+
ruby_xml_node *rxn, *n_rxn;
|
1932
|
+
VALUE n_node;
|
1933
|
+
|
1934
|
+
Data_Get_Struct(self, ruby_xml_node, rxn);
|
1935
|
+
|
1936
|
+
n_node = ruby_xml_node_new(cXMLNode, NULL); // class??
|
1937
|
+
Data_Get_Struct(n_node, ruby_xml_node, n_rxn);
|
1938
|
+
|
1939
|
+
n_rxn->node = xmlCopyNode( rxn->node, ((deep==Qnil)||(deep==Qfalse))?0:1 );
|
1940
|
+
if (rxn->node == NULL)
|
1941
|
+
return(Qnil);
|
1942
|
+
|
1943
|
+
return n_node;
|
1944
|
+
}
|
1945
|
+
|
1946
|
+
|
1947
|
+
// Rdoc needs to know
|
1948
|
+
#ifdef RDOC_NEVER_DEFINED
|
1949
|
+
mXML = rb_define_module("XML");
|
1950
|
+
#endif
|
1951
|
+
|
1952
|
+
void
|
1953
|
+
ruby_init_xml_node(void) {
|
1954
|
+
cXMLNode = rb_define_class_under(mXML, "Node", rb_cObject);
|
1955
|
+
eXMLNodeSetNamespace = rb_define_class_under(cXMLNode, "SetNamespace", rb_eException);
|
1956
|
+
eXMLNodeFailedModify = rb_define_class_under(cXMLNode, "FailedModify", rb_eException);
|
1957
|
+
eXMLNodeUnknownType = rb_define_class_under(cXMLNode, "UnknownType", rb_eException);
|
1958
|
+
|
1959
|
+
rb_define_const(cXMLNode, "SPACE_DEFAULT", INT2NUM(0));
|
1960
|
+
rb_define_const(cXMLNode, "SPACE_PRESERVE", INT2NUM(1));
|
1961
|
+
rb_define_const(cXMLNode, "SPACE_NOT_INHERIT", INT2NUM(-1));
|
1962
|
+
rb_define_const(cXMLNode, "XLINK_ACTUATE_AUTO", INT2NUM(1));
|
1963
|
+
rb_define_const(cXMLNode, "XLINK_ACTUATE_NONE", INT2NUM(0));
|
1964
|
+
rb_define_const(cXMLNode, "XLINK_ACTUATE_ONREQUEST", INT2NUM(2));
|
1965
|
+
rb_define_const(cXMLNode, "XLINK_SHOW_EMBED", INT2NUM(2));
|
1966
|
+
rb_define_const(cXMLNode, "XLINK_SHOW_NEW", INT2NUM(1));
|
1967
|
+
rb_define_const(cXMLNode, "XLINK_SHOW_NONE", INT2NUM(0));
|
1968
|
+
rb_define_const(cXMLNode, "XLINK_SHOW_REPLACE", INT2NUM(3));
|
1969
|
+
rb_define_const(cXMLNode, "XLINK_TYPE_EXTENDED", INT2NUM(2));
|
1970
|
+
rb_define_const(cXMLNode, "XLINK_TYPE_EXTENDED_SET", INT2NUM(3));
|
1971
|
+
rb_define_const(cXMLNode, "XLINK_TYPE_NONE", INT2NUM(0));
|
1972
|
+
rb_define_const(cXMLNode, "XLINK_TYPE_SIMPLE", INT2NUM(1));
|
1973
|
+
|
1974
|
+
rb_define_singleton_method(cXMLNode, "new", ruby_xml_node_initialize, -1);
|
1975
|
+
|
1976
|
+
rb_define_method(cXMLNode, "<<", ruby_xml_node_content_add, 1);
|
1977
|
+
rb_define_method(cXMLNode, "[]", ruby_xml_node_property_get, 1);
|
1978
|
+
rb_define_method(cXMLNode, "[]=", ruby_xml_node_property_set, 2);
|
1979
|
+
rb_define_method(cXMLNode, "attribute?", ruby_xml_node_attribute_q, 0);
|
1980
|
+
rb_define_method(cXMLNode, "attribute_decl?", ruby_xml_node_attribute_decl_q, 0);
|
1981
|
+
rb_define_method(cXMLNode, "base", ruby_xml_node_base_get, 0);
|
1982
|
+
rb_define_method(cXMLNode, "base=", ruby_xml_node_base_set, 1);
|
1983
|
+
rb_define_method(cXMLNode, "blank?", ruby_xml_node_empty_q, 0);
|
1984
|
+
rb_define_method(cXMLNode, "cdata?", ruby_xml_node_cdata_q, 0);
|
1985
|
+
rb_define_method(cXMLNode, "comment?", ruby_xml_node_comment_q, 0);
|
1986
|
+
rb_define_method(cXMLNode, "copy", ruby_xml_node_copy, 1);
|
1987
|
+
rb_define_method(cXMLNode, "child", ruby_xml_node_child_get, 0);
|
1988
|
+
rb_define_method(cXMLNode, "child?", ruby_xml_node_child_q, 0);
|
1989
|
+
rb_define_method(cXMLNode, "child=", ruby_xml_node_child_set, 1);
|
1990
|
+
rb_define_method(cXMLNode, "children", ruby_xml_node_child_get, 0);
|
1991
|
+
rb_define_method(cXMLNode, "children?", ruby_xml_node_child_q, 0);
|
1992
|
+
rb_define_method(cXMLNode, "content", ruby_xml_node_content_get, 0);
|
1993
|
+
rb_define_method(cXMLNode, "content=", ruby_xml_node_content_set, 1);
|
1994
|
+
rb_define_method(cXMLNode, "content_stripped", ruby_xml_node_content_stripped_get, 0);
|
1995
|
+
rb_define_method(cXMLNode, "doc", ruby_xml_node_doc, 0);
|
1996
|
+
rb_define_method(cXMLNode, "docbook_doc?", ruby_xml_node_docbook_doc_q, 0);
|
1997
|
+
rb_define_method(cXMLNode, "doctype?", ruby_xml_node_doctype_q, 0);
|
1998
|
+
rb_define_method(cXMLNode, "document?", ruby_xml_node_document_q, 0);
|
1999
|
+
rb_define_method(cXMLNode, "dtd?", ruby_xml_node_dtd_q, 0);
|
2000
|
+
rb_define_method(cXMLNode, "dump", ruby_xml_node_dump, 0);
|
2001
|
+
rb_define_method(cXMLNode, "debug_dump", ruby_xml_node_debug_dump, 0);
|
2002
|
+
rb_define_method(cXMLNode, "element?", ruby_xml_node_element_q, 0);
|
2003
|
+
rb_define_method(cXMLNode, "element_decl?", ruby_xml_node_element_decl_q, 0);
|
2004
|
+
rb_define_method(cXMLNode, "empty?", ruby_xml_node_empty_q, 0);
|
2005
|
+
rb_define_method(cXMLNode, "entity?", ruby_xml_node_entity_q, 0);
|
2006
|
+
rb_define_method(cXMLNode, "entity_ref?", ruby_xml_node_entity_ref_q, 0);
|
2007
|
+
rb_define_method(cXMLNode, "find", ruby_xml_node_find, -1);
|
2008
|
+
rb_define_method(cXMLNode, "fragment?", ruby_xml_node_fragment_q, 0);
|
2009
|
+
rb_define_method(cXMLNode, "html_doc?", ruby_xml_node_html_doc_q, 0);
|
2010
|
+
rb_define_method(cXMLNode, "lang", ruby_xml_node_lang_get, 0);
|
2011
|
+
rb_define_method(cXMLNode, "lang=", ruby_xml_node_lang_set, 1);
|
2012
|
+
rb_define_method(cXMLNode, "last", ruby_xml_node_last_get, 0);
|
2013
|
+
rb_define_method(cXMLNode, "last?", ruby_xml_node_last_q, 0);
|
2014
|
+
rb_define_method(cXMLNode, "line_num", ruby_xml_node_line_num, 0);
|
2015
|
+
rb_define_method(cXMLNode, "name", ruby_xml_node_name_get, 0);
|
2016
|
+
rb_define_method(cXMLNode, "name=", ruby_xml_node_name_set, 1);
|
2017
|
+
rb_define_method(cXMLNode, "namespace", ruby_xml_node_namespace_get, 0);
|
2018
|
+
rb_define_method(cXMLNode, "namespace_node", ruby_xml_node_namespace_get_node, 0);
|
2019
|
+
rb_define_method(cXMLNode, "namespace?", ruby_xml_node_namespace_q, 0);
|
2020
|
+
rb_define_method(cXMLNode, "namespace=", ruby_xml_node_namespace_set, -1);
|
2021
|
+
rb_define_method(cXMLNode, "next", ruby_xml_node_next_get, 0);
|
2022
|
+
rb_define_method(cXMLNode, "next?", ruby_xml_node_next_q, 0);
|
2023
|
+
rb_define_method(cXMLNode, "node_type", ruby_xml_node_type, 0);
|
2024
|
+
rb_define_method(cXMLNode, "node_type_name", ruby_xml_node_type_name, 0);
|
2025
|
+
rb_define_method(cXMLNode, "notation?", ruby_xml_node_notation_q, 0);
|
2026
|
+
rb_define_method(cXMLNode, "ns", ruby_xml_node_namespace_get, 0);
|
2027
|
+
rb_define_method(cXMLNode, "ns?", ruby_xml_node_ns_q, 0);
|
2028
|
+
rb_define_method(cXMLNode, "ns_def", ruby_xml_node_ns_def_get, 0);
|
2029
|
+
rb_define_method(cXMLNode, "ns_def?", ruby_xml_node_ns_def_q, 0);
|
2030
|
+
rb_define_method(cXMLNode, "parent", ruby_xml_node_parent_get, 0);
|
2031
|
+
rb_define_method(cXMLNode, "parent?", ruby_xml_node_parent_q, 0);
|
2032
|
+
rb_define_method(cXMLNode, "path", ruby_xml_node_path, 0);
|
2033
|
+
rb_define_method(cXMLNode, "pi?", ruby_xml_node_pi_q, 0);
|
2034
|
+
rb_define_method(cXMLNode, "pointer", ruby_xml_node_pointer, 1);
|
2035
|
+
rb_define_method(cXMLNode, "prev", ruby_xml_node_prev_get, 0);
|
2036
|
+
rb_define_method(cXMLNode, "prev?", ruby_xml_node_prev_q, 0);
|
2037
|
+
rb_define_method(cXMLNode, "property", ruby_xml_node_property_get, 1);
|
2038
|
+
rb_define_method(cXMLNode, "properties", ruby_xml_node_properties_get, 0);
|
2039
|
+
rb_define_method(cXMLNode, "properties?", ruby_xml_node_properties_q, 0);
|
2040
|
+
rb_define_method(cXMLNode, "search_ns", ruby_xml_node_search_ns, 1);
|
2041
|
+
rb_define_method(cXMLNode, "search_href", ruby_xml_node_search_href, 1);
|
2042
|
+
rb_define_method(cXMLNode, "sibling=", ruby_xml_node_sibling_set, 1);
|
2043
|
+
rb_define_method(cXMLNode, "space_preserve", ruby_xml_node_space_preserve_get, 0);
|
2044
|
+
rb_define_method(cXMLNode, "space_preserve=", ruby_xml_node_space_preserve_set, 1);
|
2045
|
+
rb_define_method(cXMLNode, "text?", ruby_xml_node_text_q, 0);
|
2046
|
+
rb_define_method(cXMLNode, "to_s", ruby_xml_node_to_s, 0);
|
2047
|
+
rb_define_method(cXMLNode, "xinclude_end?", ruby_xml_node_xinclude_end_q, 0);
|
2048
|
+
rb_define_method(cXMLNode, "xinclude_start?", ruby_xml_node_xinclude_start_q, 0);
|
2049
|
+
rb_define_method(cXMLNode, "xlink?", ruby_xml_node_xlink_q, 0);
|
2050
|
+
rb_define_method(cXMLNode, "xlink_type", ruby_xml_node_xlink_type, 0);
|
2051
|
+
rb_define_method(cXMLNode, "xlink_type_name", ruby_xml_node_xlink_type_name, 0);
|
2052
|
+
}
|