libxml-ruby 2.7.0 → 2.9.0
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.
- checksums.yaml +6 -14
- data/HISTORY +33 -11
- data/README.rdoc +7 -7
- data/Rakefile +80 -77
- data/ext/libxml/extconf.h +4 -5
- data/ext/libxml/extconf.rb +57 -118
- data/ext/libxml/libxml.c +4 -0
- data/ext/libxml/ruby_xml.c +977 -893
- data/ext/libxml/ruby_xml.h +20 -10
- data/ext/libxml/ruby_xml_attr.c +333 -333
- data/ext/libxml/ruby_xml_attr_decl.c +2 -2
- data/ext/libxml/ruby_xml_cbg.c +85 -85
- data/ext/libxml/ruby_xml_document.c +1133 -1147
- data/ext/libxml/ruby_xml_dtd.c +261 -268
- data/ext/libxml/ruby_xml_encoding.c +262 -260
- data/ext/libxml/ruby_xml_encoding.h +19 -19
- data/ext/libxml/ruby_xml_html_parser_context.c +337 -338
- data/ext/libxml/ruby_xml_input_cbg.c +191 -191
- data/ext/libxml/ruby_xml_io.c +52 -50
- data/ext/libxml/ruby_xml_namespace.c +2 -2
- data/ext/libxml/ruby_xml_node.c +1446 -1452
- data/ext/libxml/ruby_xml_parser_context.c +999 -1001
- data/ext/libxml/ruby_xml_reader.c +1226 -1228
- data/ext/libxml/ruby_xml_relaxng.c +110 -111
- data/ext/libxml/ruby_xml_sax2_handler.c +326 -328
- data/ext/libxml/ruby_xml_schema.c +300 -301
- data/ext/libxml/ruby_xml_version.h +3 -3
- data/ext/libxml/ruby_xml_writer.c +34 -16
- data/ext/libxml/ruby_xml_xpath.c +188 -187
- data/ext/libxml/ruby_xml_xpath_context.c +360 -361
- data/ext/libxml/ruby_xml_xpath_object.c +335 -335
- data/libxml-ruby.gemspec +47 -44
- data/test/tc_attr.rb +5 -7
- data/test/tc_attr_decl.rb +5 -6
- data/test/tc_attributes.rb +1 -2
- data/test/tc_canonicalize.rb +1 -2
- data/test/tc_deprecated_require.rb +1 -2
- data/test/tc_document.rb +4 -5
- data/test/tc_document_write.rb +2 -3
- data/test/tc_dtd.rb +4 -5
- data/test/tc_encoding.rb +126 -126
- data/test/tc_encoding_sax.rb +4 -3
- data/test/tc_error.rb +14 -15
- data/test/tc_html_parser.rb +15 -7
- data/test/tc_html_parser_context.rb +1 -2
- data/test/tc_namespace.rb +2 -3
- data/test/tc_namespaces.rb +5 -6
- data/test/tc_node.rb +2 -3
- data/test/tc_node_cdata.rb +2 -3
- data/test/tc_node_comment.rb +1 -2
- data/test/tc_node_copy.rb +1 -2
- data/test/tc_node_edit.rb +5 -7
- data/test/tc_node_pi.rb +1 -2
- data/test/tc_node_text.rb +2 -3
- data/test/tc_node_write.rb +2 -3
- data/test/tc_node_xlink.rb +1 -2
- data/test/tc_parser.rb +18 -24
- data/test/tc_parser_context.rb +6 -7
- data/test/tc_properties.rb +1 -2
- data/test/tc_reader.rb +9 -10
- data/test/tc_relaxng.rb +4 -5
- data/test/tc_sax_parser.rb +9 -10
- data/test/tc_schema.rb +4 -5
- data/test/tc_traversal.rb +1 -2
- data/test/tc_writer.rb +1 -2
- data/test/tc_xinclude.rb +1 -2
- data/test/tc_xml.rb +1 -2
- data/test/tc_xpath.rb +8 -9
- data/test/tc_xpath_context.rb +3 -4
- data/test/tc_xpath_expression.rb +3 -4
- data/test/tc_xpointer.rb +1 -3
- data/test/test_helper.rb +3 -1
- data/test/test_suite.rb +0 -1
- metadata +90 -72
- data/test/etc_doc_to_s.rb +0 -21
- data/test/ets_doc_file.rb +0 -17
- data/test/ets_doc_to_s.rb +0 -23
- data/test/ets_gpx.rb +0 -28
- data/test/ets_node_gc.rb +0 -23
- data/test/ets_test.xml +0 -2
- data/test/ets_tsr.rb +0 -11
- data/test/model/kml_sample.xml +0 -915
- data/test/remove_test.rb +0 -9
- data/test/tc_gc.rb +0 -86
- data/test/tc_parser.rb.orig +0 -384
@@ -34,6 +34,7 @@ typedef struct {
|
|
34
34
|
xmlBufferPtr buffer;
|
35
35
|
xmlTextWriterPtr writer;
|
36
36
|
rxmlw_output_type output_type;
|
37
|
+
int closed;
|
37
38
|
} rxml_writer_object;
|
38
39
|
|
39
40
|
#ifdef HAVE_RUBY_ENCODING_H
|
@@ -72,6 +73,8 @@ static void rxml_writer_free(rxml_writer_object *rwo)
|
|
72
73
|
xmlBufferFree(rwo->buffer);
|
73
74
|
}
|
74
75
|
#endif
|
76
|
+
|
77
|
+
rwo->closed = 1;
|
75
78
|
xmlFreeTextWriter(rwo->writer);
|
76
79
|
xfree(rwo);
|
77
80
|
}
|
@@ -97,6 +100,17 @@ static rxml_writer_object *rxml_textwriter_get(VALUE obj)
|
|
97
100
|
return rwo;
|
98
101
|
}
|
99
102
|
|
103
|
+
int rxml_writer_write_callback(void *context, const char *buffer, int len)
|
104
|
+
{
|
105
|
+
rxml_writer_object *rwo = context;
|
106
|
+
|
107
|
+
if(rwo->closed){
|
108
|
+
return 0;
|
109
|
+
}else{
|
110
|
+
return rxml_write_callback((void *)rwo->output, buffer, len);
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
100
114
|
/* ===== public class methods ===== */
|
101
115
|
|
102
116
|
/* call-seq:
|
@@ -122,11 +136,12 @@ xmlCharEncodingHandlerPtr xmlFindCharEncodingHandler(const char * name);
|
|
122
136
|
rwo = ALLOC(rxml_writer_object);
|
123
137
|
rwo->output = io;
|
124
138
|
rwo->buffer = NULL;
|
139
|
+
rwo->closed = 0;
|
125
140
|
#ifdef HAVE_RUBY_ENCODING_H
|
126
141
|
rwo->encoding = NULL;
|
127
142
|
#endif /* HAVE_RUBY_ENCODING_H */
|
128
143
|
rwo->output_type = RXMLW_OUTPUT_IO;
|
129
|
-
if (NULL == (out = xmlOutputBufferCreateIO(
|
144
|
+
if (NULL == (out = xmlOutputBufferCreateIO(rxml_writer_write_callback, NULL, (void *) rwo, NULL))) {
|
130
145
|
rxml_raise(&xmlLastError);
|
131
146
|
}
|
132
147
|
if (NULL == (rwo->writer = xmlNewTextWriter(out))) {
|
@@ -150,6 +165,7 @@ static VALUE rxml_writer_file(VALUE klass, VALUE filename)
|
|
150
165
|
rwo = ALLOC(rxml_writer_object);
|
151
166
|
rwo->output = Qnil;
|
152
167
|
rwo->buffer = NULL;
|
168
|
+
rwo->closed = 0;
|
153
169
|
#ifdef HAVE_RUBY_ENCODING_H
|
154
170
|
rwo->encoding = NULL;
|
155
171
|
#endif /* HAVE_RUBY_ENCODING_H */
|
@@ -172,6 +188,7 @@ static VALUE rxml_writer_string(VALUE klass)
|
|
172
188
|
|
173
189
|
rwo = ALLOC(rxml_writer_object);
|
174
190
|
rwo->output = Qnil;
|
191
|
+
rwo->closed = 0;
|
175
192
|
#ifdef HAVE_RUBY_ENCODING_H
|
176
193
|
rwo->encoding = NULL;
|
177
194
|
#endif /* HAVE_RUBY_ENCODING_H */
|
@@ -200,6 +217,7 @@ static VALUE rxml_writer_doc(VALUE klass)
|
|
200
217
|
rwo = ALLOC(rxml_writer_object);
|
201
218
|
rwo->buffer = NULL;
|
202
219
|
rwo->output = Qnil;
|
220
|
+
rwo->closed = 0;
|
203
221
|
#ifdef HAVE_RUBY_ENCODING_H
|
204
222
|
rwo->encoding = NULL;
|
205
223
|
#endif /* HAVE_RUBY_ENCODING_H */
|
@@ -234,11 +252,12 @@ static VALUE rxml_writer_flush(int argc, VALUE *argv, VALUE self)
|
|
234
252
|
if (-1 == (ret = xmlTextWriterFlush(rwo->writer))) {
|
235
253
|
rxml_raise(&xmlLastError);
|
236
254
|
}
|
255
|
+
|
237
256
|
if (NULL != rwo->buffer) {
|
238
257
|
VALUE content;
|
239
258
|
|
240
259
|
#ifdef HAVE_RUBY_ENCODING_H
|
241
|
-
content = rb_external_str_new_with_enc(rwo->buffer->content, rwo->buffer->use, rwo->encoding);
|
260
|
+
content = rb_external_str_new_with_enc((const char*)rwo->buffer->content, rwo->buffer->use, rwo->encoding);
|
242
261
|
#else
|
243
262
|
content = rb_str_new(rwo->buffer->content, rwo->buffer->use);
|
244
263
|
#endif /* HAVE_RUBY_ENCODING_H */
|
@@ -261,20 +280,20 @@ static VALUE rxml_writer_flush(int argc, VALUE *argv, VALUE self)
|
|
261
280
|
*/
|
262
281
|
static VALUE rxml_writer_result(VALUE self)
|
263
282
|
{
|
264
|
-
VALUE ret;
|
265
|
-
rxml_writer_object *rwo;
|
283
|
+
VALUE ret = Qnil;
|
284
|
+
rxml_writer_object *rwo = rxml_textwriter_get(self);
|
285
|
+
int bytesWritten = xmlTextWriterFlush(rwo->writer);
|
266
286
|
|
267
|
-
|
268
|
-
rwo = rxml_textwriter_get(self);
|
269
|
-
if (-1 == (ret = xmlTextWriterFlush(rwo->writer))) {
|
287
|
+
if (bytesWritten == -1) {
|
270
288
|
rxml_raise(&xmlLastError);
|
271
289
|
}
|
290
|
+
|
272
291
|
switch (rwo->output_type) {
|
273
292
|
case RXMLW_OUTPUT_DOC:
|
274
293
|
ret = rwo->output;
|
275
294
|
break;
|
276
295
|
case RXMLW_OUTPUT_STRING:
|
277
|
-
ret = rxml_writer_c_to_ruby_string(rwo->buffer->content, rwo->buffer->use);
|
296
|
+
ret = rxml_writer_c_to_ruby_string((const char*)rwo->buffer->content, rwo->buffer->use);
|
278
297
|
break;
|
279
298
|
case RXMLW_OUTPUT_IO:
|
280
299
|
case RXMLW_OUTPUT_NONE:
|
@@ -315,7 +334,8 @@ static VALUE numeric_rxml_writer_void(VALUE obj, int (*fn)(xmlTextWriterPtr))
|
|
315
334
|
static VALUE numeric_rxml_writer_va_strings(VALUE obj, VALUE pe, size_t strings_count, int (*fn)(ANYARGS), ...)
|
316
335
|
{
|
317
336
|
va_list ap;
|
318
|
-
|
337
|
+
size_t argc;
|
338
|
+
int ret = -1;
|
319
339
|
rxml_writer_object *rwo;
|
320
340
|
const xmlChar *argv[XMLWRITER_MAX_STRING_ARGS];
|
321
341
|
VALUE utf8[XMLWRITER_MAX_STRING_ARGS], orig[XMLWRITER_MAX_STRING_ARGS];
|
@@ -323,7 +343,6 @@ static VALUE numeric_rxml_writer_va_strings(VALUE obj, VALUE pe, size_t strings_
|
|
323
343
|
if (strings_count > XMLWRITER_MAX_STRING_ARGS) {
|
324
344
|
rb_bug("more arguments than expected");
|
325
345
|
}
|
326
|
-
ret = -1;
|
327
346
|
va_start(ap, fn);
|
328
347
|
rwo = rxml_textwriter_get(obj);
|
329
348
|
for (argc = 0; argc < strings_count; argc++) {
|
@@ -746,12 +765,11 @@ static VALUE rxml_writer_end_cdata(VALUE self)
|
|
746
765
|
static VALUE rxml_writer_start_document(int argc, VALUE *argv, VALUE self)
|
747
766
|
{
|
748
767
|
int ret;
|
749
|
-
VALUE options;
|
768
|
+
VALUE options = Qnil;
|
750
769
|
rxml_writer_object *rwo;
|
751
|
-
const
|
770
|
+
const xmlChar *xencoding = NULL;
|
771
|
+
const char *xstandalone = NULL;
|
752
772
|
|
753
|
-
options = Qnil;
|
754
|
-
xstandalone = xencoding = NULL;
|
755
773
|
rb_scan_args(argc, argv, "01", &options);
|
756
774
|
if (!NIL_P(options)) {
|
757
775
|
VALUE encoding, standalone;
|
@@ -759,7 +777,7 @@ static VALUE rxml_writer_start_document(int argc, VALUE *argv, VALUE self)
|
|
759
777
|
encoding = standalone = Qnil;
|
760
778
|
Check_Type(options, T_HASH);
|
761
779
|
encoding = rb_hash_aref(options, sEncoding);
|
762
|
-
xencoding = NIL_P(encoding) ? NULL : xmlGetCharEncodingName(NUM2INT(encoding));
|
780
|
+
xencoding = NIL_P(encoding) ? NULL : (const xmlChar*)xmlGetCharEncodingName(NUM2INT(encoding));
|
763
781
|
standalone = rb_hash_aref(options, sStandalone);
|
764
782
|
if (NIL_P(standalone)) {
|
765
783
|
xstandalone = NULL;
|
@@ -771,7 +789,7 @@ static VALUE rxml_writer_start_document(int argc, VALUE *argv, VALUE self)
|
|
771
789
|
#ifdef HAVE_RUBY_ENCODING_H
|
772
790
|
rwo->encoding = rxml_figure_encoding(xencoding);
|
773
791
|
#endif /* !HAVE_RUBY_ENCODING_H */
|
774
|
-
ret = xmlTextWriterStartDocument(rwo->writer, NULL, xencoding, xstandalone);
|
792
|
+
ret = xmlTextWriterStartDocument(rwo->writer, NULL, (const char*)xencoding, xstandalone);
|
775
793
|
|
776
794
|
return (-1 == ret ? Qfalse : Qtrue);
|
777
795
|
}
|
data/ext/libxml/ruby_xml_xpath.c
CHANGED
@@ -1,187 +1,188 @@
|
|
1
|
-
/*
|
2
|
-
* Document-class: LibXML::XML::XPath
|
3
|
-
*
|
4
|
-
* The XML::XPath module is used to query XML documents. It is
|
5
|
-
* usually accessed via the XML::Document#find or
|
6
|
-
* XML::Node#find methods. For example:
|
7
|
-
*
|
8
|
-
* document.find('/foo', namespaces) -> XML::XPath::Object
|
9
|
-
*
|
10
|
-
* The optional namespaces parameter can be a string, array or
|
11
|
-
* hash table.
|
12
|
-
*
|
13
|
-
* document.find('/foo', 'xlink:http://www.w3.org/1999/xlink')
|
14
|
-
* document.find('/foo', ['xlink:http://www.w3.org/1999/xlink',
|
15
|
-
* 'xi:http://www.w3.org/2001/XInclude')
|
16
|
-
* document.find('/foo', 'xlink' => 'http://www.w3.org/1999/xlink',
|
17
|
-
* 'xi' => 'http://www.w3.org/2001/XInclude')
|
18
|
-
*
|
19
|
-
*
|
20
|
-
* === Working With Default Namespaces
|
21
|
-
*
|
22
|
-
* Finding namespaced elements and attributes can be tricky.
|
23
|
-
* Lets work through an example of a document with a default
|
24
|
-
* namespace:
|
25
|
-
*
|
26
|
-
* <?xml version="1.0" encoding="utf-8"?>
|
27
|
-
* <feed xmlns="http://www.w3.org/2005/Atom">
|
28
|
-
* <title type="text">Phil Bogle's Contacts</title>
|
29
|
-
* </feed>
|
30
|
-
*
|
31
|
-
* To find nodes you must define the atom namespace for
|
32
|
-
* libxml. One way to do this is:
|
33
|
-
*
|
34
|
-
* node = doc.find('atom:title', 'atom:http://www.w3.org/2005/Atom')
|
35
|
-
*
|
36
|
-
* Alternatively, you can register the default namespace like this:
|
37
|
-
*
|
38
|
-
* doc.root.namespaces.default_prefix = 'atom'
|
39
|
-
* node = doc.find('atom:title')
|
40
|
-
*
|
41
|
-
* === More Complex Namespace Examples
|
42
|
-
*
|
43
|
-
* Lets work through some more complex examples using the
|
44
|
-
* following xml document:
|
45
|
-
*
|
46
|
-
* <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
47
|
-
* <soap:Body>
|
48
|
-
* <getManufacturerNamesResponse xmlns="http://services.somewhere.com">
|
49
|
-
* <IDAndNameList xmlns="http://services.somewhere.com">
|
50
|
-
* <ns1:IdAndName xmlns:ns1="http://domain.somewhere.com"/>
|
51
|
-
* </IDAndNameList>
|
52
|
-
* </getManufacturerNamesResponse>
|
53
|
-
*
|
54
|
-
*
|
55
|
-
*
|
56
|
-
* #
|
57
|
-
*
|
58
|
-
*
|
59
|
-
*
|
60
|
-
* #
|
61
|
-
*
|
62
|
-
*
|
63
|
-
*
|
64
|
-
*
|
65
|
-
* #
|
66
|
-
* # it
|
67
|
-
*
|
68
|
-
*
|
69
|
-
*
|
70
|
-
*
|
71
|
-
* #
|
72
|
-
*
|
73
|
-
*
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
case
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
case
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
1
|
+
/*
|
2
|
+
* Document-class: LibXML::XML::XPath
|
3
|
+
*
|
4
|
+
* The XML::XPath module is used to query XML documents. It is
|
5
|
+
* usually accessed via the XML::Document#find or
|
6
|
+
* XML::Node#find methods. For example:
|
7
|
+
*
|
8
|
+
* document.find('/foo', namespaces) -> XML::XPath::Object
|
9
|
+
*
|
10
|
+
* The optional namespaces parameter can be a string, array or
|
11
|
+
* hash table.
|
12
|
+
*
|
13
|
+
* document.find('/foo', 'xlink:http://www.w3.org/1999/xlink')
|
14
|
+
* document.find('/foo', ['xlink:http://www.w3.org/1999/xlink',
|
15
|
+
* 'xi:http://www.w3.org/2001/XInclude')
|
16
|
+
* document.find('/foo', 'xlink' => 'http://www.w3.org/1999/xlink',
|
17
|
+
* 'xi' => 'http://www.w3.org/2001/XInclude')
|
18
|
+
*
|
19
|
+
*
|
20
|
+
* === Working With Default Namespaces
|
21
|
+
*
|
22
|
+
* Finding namespaced elements and attributes can be tricky.
|
23
|
+
* Lets work through an example of a document with a default
|
24
|
+
* namespace:
|
25
|
+
*
|
26
|
+
* <?xml version="1.0" encoding="utf-8"?>
|
27
|
+
* <feed xmlns="http://www.w3.org/2005/Atom">
|
28
|
+
* <title type="text">Phil Bogle's Contacts</title>
|
29
|
+
* </feed>
|
30
|
+
*
|
31
|
+
* To find nodes you must define the atom namespace for
|
32
|
+
* libxml. One way to do this is:
|
33
|
+
*
|
34
|
+
* node = doc.find('atom:title', 'atom:http://www.w3.org/2005/Atom')
|
35
|
+
*
|
36
|
+
* Alternatively, you can register the default namespace like this:
|
37
|
+
*
|
38
|
+
* doc.root.namespaces.default_prefix = 'atom'
|
39
|
+
* node = doc.find('atom:title')
|
40
|
+
*
|
41
|
+
* === More Complex Namespace Examples
|
42
|
+
*
|
43
|
+
* Lets work through some more complex examples using the
|
44
|
+
* following xml document:
|
45
|
+
*
|
46
|
+
* <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
47
|
+
* <soap:Body>
|
48
|
+
* <getManufacturerNamesResponse xmlns="http://services.somewhere.com">
|
49
|
+
* <IDAndNameList xmlns="http://services.somewhere.com">
|
50
|
+
* <ns1:IdAndName xmlns:ns1="http://domain.somewhere.com"/>
|
51
|
+
* </IDAndNameList>
|
52
|
+
* </getManufacturerNamesResponse>
|
53
|
+
* </soap:Body>
|
54
|
+
* </soap:Envelope>
|
55
|
+
*
|
56
|
+
* # Since the soap namespace is defined on the root
|
57
|
+
* # node we can directly use it.
|
58
|
+
* doc.find('/soap:Envelope')
|
59
|
+
*
|
60
|
+
* # Since the ns1 namespace is not defined on the root node
|
61
|
+
* # we have to first register it with the xpath engine.
|
62
|
+
* doc.find('//ns1:IdAndName',
|
63
|
+
* 'ns1:http://domain.somewhere.com')
|
64
|
+
*
|
65
|
+
* # Since the getManufacturerNamesResponse element uses a default
|
66
|
+
* # namespace we first have to give it a prefix and register
|
67
|
+
* # it with the xpath engine.
|
68
|
+
* doc.find('//ns:getManufacturerNamesResponse',
|
69
|
+
* 'ns:http://services.somewhere.com')
|
70
|
+
*
|
71
|
+
* # Here is an example showing a complex namespace aware
|
72
|
+
* # xpath expression.
|
73
|
+
* doc.find('/soap:Envelope/soap:Body/ns0:getManufacturerNamesResponse/ns0:IDAndNameList/ns1:IdAndName',
|
74
|
+
* ['ns0:http://services.somewhere.com', 'ns1:http://domain.somewhere.com'])
|
75
|
+
*/
|
76
|
+
|
77
|
+
|
78
|
+
#include "ruby_libxml.h"
|
79
|
+
|
80
|
+
VALUE mXPath;
|
81
|
+
|
82
|
+
VALUE
|
83
|
+
rxml_xpath_to_value(xmlXPathContextPtr xctxt, xmlXPathObjectPtr xobject) {
|
84
|
+
VALUE result;
|
85
|
+
int type;
|
86
|
+
|
87
|
+
if (xobject == NULL) {
|
88
|
+
/* xmlLastError is different than xctxt->lastError. Use
|
89
|
+
xmlLastError since it has the message set while xctxt->lastError
|
90
|
+
does not. */
|
91
|
+
xmlErrorPtr xerror = xmlGetLastError();
|
92
|
+
rxml_raise(xerror);
|
93
|
+
}
|
94
|
+
|
95
|
+
switch (type = xobject->type) {
|
96
|
+
case XPATH_NODESET:
|
97
|
+
result = rxml_xpath_object_wrap(xctxt->doc, xobject);
|
98
|
+
break;
|
99
|
+
case XPATH_BOOLEAN:
|
100
|
+
result = (xobject->boolval != 0) ? Qtrue : Qfalse;
|
101
|
+
xmlXPathFreeObject(xobject);
|
102
|
+
break;
|
103
|
+
case XPATH_NUMBER:
|
104
|
+
result = rb_float_new(xobject->floatval);
|
105
|
+
xmlXPathFreeObject(xobject);
|
106
|
+
break;
|
107
|
+
case XPATH_STRING:
|
108
|
+
result = rxml_new_cstr(xobject->stringval, xctxt->doc->encoding);
|
109
|
+
xmlXPathFreeObject(xobject);
|
110
|
+
break;
|
111
|
+
default:
|
112
|
+
xmlXPathFreeObject(xobject);
|
113
|
+
rb_raise(rb_eTypeError,
|
114
|
+
"can't convert XPath object of type %d to Ruby value", type
|
115
|
+
);
|
116
|
+
}
|
117
|
+
|
118
|
+
return result;
|
119
|
+
}
|
120
|
+
|
121
|
+
xmlXPathObjectPtr
|
122
|
+
rxml_xpath_from_value(VALUE value) {
|
123
|
+
xmlXPathObjectPtr result = NULL;
|
124
|
+
|
125
|
+
switch (TYPE(value)) {
|
126
|
+
case T_TRUE:
|
127
|
+
case T_FALSE:
|
128
|
+
result = xmlXPathNewBoolean(RTEST(value));
|
129
|
+
break;
|
130
|
+
case T_FIXNUM:
|
131
|
+
case T_FLOAT:
|
132
|
+
result = xmlXPathNewFloat(NUM2DBL(value));
|
133
|
+
break;
|
134
|
+
case T_STRING:
|
135
|
+
result = xmlXPathWrapString(xmlStrdup((const xmlChar *)StringValuePtr(value)));
|
136
|
+
break;
|
137
|
+
case T_NIL:
|
138
|
+
result = xmlXPathNewNodeSet(NULL);
|
139
|
+
break;
|
140
|
+
case T_ARRAY: {
|
141
|
+
long i, j;
|
142
|
+
result = xmlXPathNewNodeSet(NULL);
|
143
|
+
|
144
|
+
for (i = RARRAY_LEN(value); i > 0; i--) {
|
145
|
+
xmlXPathObjectPtr obj = rxml_xpath_from_value(rb_ary_shift(value));
|
146
|
+
|
147
|
+
if ((obj->nodesetval != NULL) && (obj->nodesetval->nodeNr != 0)) {
|
148
|
+
for (j = 0; j < obj->nodesetval->nodeNr; j++) {
|
149
|
+
xmlXPathNodeSetAdd(result->nodesetval, obj->nodesetval->nodeTab[j]);
|
150
|
+
}
|
151
|
+
}
|
152
|
+
}
|
153
|
+
break;
|
154
|
+
}
|
155
|
+
default:
|
156
|
+
rb_raise(rb_eTypeError,
|
157
|
+
"can't convert object of type %s to XPath object", rb_obj_classname(value)
|
158
|
+
);
|
159
|
+
}
|
160
|
+
|
161
|
+
return result;
|
162
|
+
}
|
163
|
+
|
164
|
+
void rxml_init_xpath(void)
|
165
|
+
{
|
166
|
+
mXPath = rb_define_module_under(mXML, "XPath");
|
167
|
+
|
168
|
+
/* 0: Undefined value. */
|
169
|
+
rb_define_const(mXPath, "UNDEFINED", INT2NUM(XPATH_UNDEFINED));
|
170
|
+
/* 1: A nodeset, will be wrapped by XPath Object. */
|
171
|
+
rb_define_const(mXPath, "NODESET", INT2NUM(XPATH_NODESET));
|
172
|
+
/* 2: A boolean value. */
|
173
|
+
rb_define_const(mXPath, "BOOLEAN", INT2NUM(XPATH_BOOLEAN));
|
174
|
+
/* 3: A numeric value. */
|
175
|
+
rb_define_const(mXPath, "NUMBER", INT2NUM(XPATH_NUMBER));
|
176
|
+
/* 4: A string value. */
|
177
|
+
rb_define_const(mXPath, "STRING", INT2NUM(XPATH_STRING));
|
178
|
+
/* 5: An xpointer point */
|
179
|
+
rb_define_const(mXPath, "POINT", INT2NUM(XPATH_POINT));
|
180
|
+
/* 6: An xpointer range */
|
181
|
+
rb_define_const(mXPath, "RANGE", INT2NUM(XPATH_RANGE));
|
182
|
+
/* 7: An xpointer location set */
|
183
|
+
rb_define_const(mXPath, "LOCATIONSET", INT2NUM(XPATH_LOCATIONSET));
|
184
|
+
/* 8: XPath user type */
|
185
|
+
rb_define_const(mXPath, "USERS", INT2NUM(XPATH_USERS));
|
186
|
+
/* 9: An XSLT value tree, non modifiable */
|
187
|
+
rb_define_const(mXPath, "XSLT_TREE", INT2NUM(XPATH_XSLT_TREE));
|
188
|
+
}
|