libxml-ruby 2.8.0 → 2.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY +15 -0
  3. data/README.rdoc +7 -7
  4. data/Rakefile +80 -78
  5. data/ext/libxml/extconf.h +4 -0
  6. data/ext/libxml/extconf.rb +57 -116
  7. data/ext/libxml/libxml.c +4 -0
  8. data/ext/libxml/ruby_xml.c +977 -893
  9. data/ext/libxml/ruby_xml.h +20 -10
  10. data/ext/libxml/ruby_xml_attr.c +333 -333
  11. data/ext/libxml/ruby_xml_attr_decl.c +2 -2
  12. data/ext/libxml/ruby_xml_cbg.c +85 -85
  13. data/ext/libxml/ruby_xml_document.c +1133 -1147
  14. data/ext/libxml/ruby_xml_dtd.c +261 -268
  15. data/ext/libxml/ruby_xml_encoding.c +262 -260
  16. data/ext/libxml/ruby_xml_encoding.h +19 -19
  17. data/ext/libxml/ruby_xml_html_parser_context.c +337 -338
  18. data/ext/libxml/ruby_xml_input_cbg.c +191 -191
  19. data/ext/libxml/ruby_xml_io.c +52 -50
  20. data/ext/libxml/ruby_xml_namespace.c +2 -2
  21. data/ext/libxml/ruby_xml_node.c +1446 -1452
  22. data/ext/libxml/ruby_xml_parser_context.c +999 -1001
  23. data/ext/libxml/ruby_xml_reader.c +1226 -1228
  24. data/ext/libxml/ruby_xml_relaxng.c +110 -111
  25. data/ext/libxml/ruby_xml_sax2_handler.c +326 -328
  26. data/ext/libxml/ruby_xml_schema.c +300 -301
  27. data/ext/libxml/ruby_xml_version.h +3 -3
  28. data/ext/libxml/ruby_xml_writer.c +14 -15
  29. data/ext/libxml/ruby_xml_xpath.c +188 -188
  30. data/ext/libxml/ruby_xml_xpath_context.c +360 -361
  31. data/ext/libxml/ruby_xml_xpath_object.c +335 -335
  32. data/libxml-ruby.gemspec +47 -44
  33. data/test/tc_attr.rb +5 -7
  34. data/test/tc_attr_decl.rb +5 -6
  35. data/test/tc_attributes.rb +1 -2
  36. data/test/tc_canonicalize.rb +1 -2
  37. data/test/tc_deprecated_require.rb +1 -2
  38. data/test/tc_document.rb +4 -5
  39. data/test/tc_document_write.rb +2 -3
  40. data/test/tc_dtd.rb +4 -5
  41. data/test/tc_encoding.rb +126 -126
  42. data/test/tc_encoding_sax.rb +4 -3
  43. data/test/tc_error.rb +14 -15
  44. data/test/tc_html_parser.rb +15 -7
  45. data/test/tc_html_parser_context.rb +1 -2
  46. data/test/tc_namespace.rb +2 -3
  47. data/test/tc_namespaces.rb +5 -6
  48. data/test/tc_node.rb +2 -3
  49. data/test/tc_node_cdata.rb +2 -3
  50. data/test/tc_node_comment.rb +1 -2
  51. data/test/tc_node_copy.rb +1 -2
  52. data/test/tc_node_edit.rb +5 -7
  53. data/test/tc_node_pi.rb +1 -2
  54. data/test/tc_node_text.rb +2 -3
  55. data/test/tc_node_write.rb +2 -3
  56. data/test/tc_node_xlink.rb +1 -2
  57. data/test/tc_parser.rb +18 -24
  58. data/test/tc_parser_context.rb +6 -7
  59. data/test/tc_properties.rb +1 -2
  60. data/test/tc_reader.rb +9 -10
  61. data/test/tc_relaxng.rb +4 -5
  62. data/test/tc_sax_parser.rb +9 -10
  63. data/test/tc_schema.rb +4 -5
  64. data/test/tc_traversal.rb +1 -2
  65. data/test/tc_writer.rb +1 -2
  66. data/test/tc_xinclude.rb +1 -2
  67. data/test/tc_xml.rb +1 -2
  68. data/test/tc_xpath.rb +8 -9
  69. data/test/tc_xpath_context.rb +3 -4
  70. data/test/tc_xpath_expression.rb +3 -4
  71. data/test/tc_xpointer.rb +1 -3
  72. data/test/test_helper.rb +3 -1
  73. data/test/test_suite.rb +0 -1
  74. metadata +47 -11
  75. data/test/etc_doc_to_s.rb +0 -21
  76. data/test/ets_doc_file.rb +0 -17
  77. data/test/ets_doc_to_s.rb +0 -23
  78. data/test/ets_gpx.rb +0 -28
  79. data/test/ets_node_gc.rb +0 -23
  80. data/test/ets_test.xml +0 -2
  81. data/test/ets_tsr.rb +0 -11
@@ -1,9 +1,9 @@
1
1
  /* Don't nuke this block! It is used for automatically updating the
2
2
  * versions below. VERSION = string formatting, VERNUM = numbered
3
3
  * version for inline testing: increment both or none at all.*/
4
- #define RUBY_LIBXML_VERSION "2.8.0"
5
- #define RUBY_LIBXML_VERNUM 280
4
+ #define RUBY_LIBXML_VERSION "2.9.0"
5
+ #define RUBY_LIBXML_VERNUM 290
6
6
  #define RUBY_LIBXML_VER_MAJ 2
7
- #define RUBY_LIBXML_VER_MIN 8
7
+ #define RUBY_LIBXML_VER_MIN 9
8
8
  #define RUBY_LIBXML_VER_MIC 0
9
9
  #define RUBY_LIBXML_VER_PATCH 0
@@ -257,7 +257,7 @@ static VALUE rxml_writer_flush(int argc, VALUE *argv, VALUE self)
257
257
  VALUE content;
258
258
 
259
259
  #ifdef HAVE_RUBY_ENCODING_H
260
- 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);
261
261
  #else
262
262
  content = rb_str_new(rwo->buffer->content, rwo->buffer->use);
263
263
  #endif /* HAVE_RUBY_ENCODING_H */
@@ -280,20 +280,20 @@ static VALUE rxml_writer_flush(int argc, VALUE *argv, VALUE self)
280
280
  */
281
281
  static VALUE rxml_writer_result(VALUE self)
282
282
  {
283
- VALUE ret;
284
- rxml_writer_object *rwo;
283
+ VALUE ret = Qnil;
284
+ rxml_writer_object *rwo = rxml_textwriter_get(self);
285
+ int bytesWritten = xmlTextWriterFlush(rwo->writer);
285
286
 
286
- ret = Qnil;
287
- rwo = rxml_textwriter_get(self);
288
- if (-1 == (ret = xmlTextWriterFlush(rwo->writer))) {
287
+ if (bytesWritten == -1) {
289
288
  rxml_raise(&xmlLastError);
290
289
  }
290
+
291
291
  switch (rwo->output_type) {
292
292
  case RXMLW_OUTPUT_DOC:
293
293
  ret = rwo->output;
294
294
  break;
295
295
  case RXMLW_OUTPUT_STRING:
296
- 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);
297
297
  break;
298
298
  case RXMLW_OUTPUT_IO:
299
299
  case RXMLW_OUTPUT_NONE:
@@ -334,7 +334,8 @@ static VALUE numeric_rxml_writer_void(VALUE obj, int (*fn)(xmlTextWriterPtr))
334
334
  static VALUE numeric_rxml_writer_va_strings(VALUE obj, VALUE pe, size_t strings_count, int (*fn)(ANYARGS), ...)
335
335
  {
336
336
  va_list ap;
337
- int argc, ret;
337
+ size_t argc;
338
+ int ret = -1;
338
339
  rxml_writer_object *rwo;
339
340
  const xmlChar *argv[XMLWRITER_MAX_STRING_ARGS];
340
341
  VALUE utf8[XMLWRITER_MAX_STRING_ARGS], orig[XMLWRITER_MAX_STRING_ARGS];
@@ -342,7 +343,6 @@ static VALUE numeric_rxml_writer_va_strings(VALUE obj, VALUE pe, size_t strings_
342
343
  if (strings_count > XMLWRITER_MAX_STRING_ARGS) {
343
344
  rb_bug("more arguments than expected");
344
345
  }
345
- ret = -1;
346
346
  va_start(ap, fn);
347
347
  rwo = rxml_textwriter_get(obj);
348
348
  for (argc = 0; argc < strings_count; argc++) {
@@ -765,12 +765,11 @@ static VALUE rxml_writer_end_cdata(VALUE self)
765
765
  static VALUE rxml_writer_start_document(int argc, VALUE *argv, VALUE self)
766
766
  {
767
767
  int ret;
768
- VALUE options;
768
+ VALUE options = Qnil;
769
769
  rxml_writer_object *rwo;
770
- const char *xencoding, *xstandalone;
770
+ const xmlChar *xencoding = NULL;
771
+ const char *xstandalone = NULL;
771
772
 
772
- options = Qnil;
773
- xstandalone = xencoding = NULL;
774
773
  rb_scan_args(argc, argv, "01", &options);
775
774
  if (!NIL_P(options)) {
776
775
  VALUE encoding, standalone;
@@ -778,7 +777,7 @@ static VALUE rxml_writer_start_document(int argc, VALUE *argv, VALUE self)
778
777
  encoding = standalone = Qnil;
779
778
  Check_Type(options, T_HASH);
780
779
  encoding = rb_hash_aref(options, sEncoding);
781
- xencoding = NIL_P(encoding) ? NULL : xmlGetCharEncodingName(NUM2INT(encoding));
780
+ xencoding = NIL_P(encoding) ? NULL : (const xmlChar*)xmlGetCharEncodingName(NUM2INT(encoding));
782
781
  standalone = rb_hash_aref(options, sStandalone);
783
782
  if (NIL_P(standalone)) {
784
783
  xstandalone = NULL;
@@ -790,7 +789,7 @@ static VALUE rxml_writer_start_document(int argc, VALUE *argv, VALUE self)
790
789
  #ifdef HAVE_RUBY_ENCODING_H
791
790
  rwo->encoding = rxml_figure_encoding(xencoding);
792
791
  #endif /* !HAVE_RUBY_ENCODING_H */
793
- ret = xmlTextWriterStartDocument(rwo->writer, NULL, xencoding, xstandalone);
792
+ ret = xmlTextWriterStartDocument(rwo->writer, NULL, (const char*)xencoding, xstandalone);
794
793
 
795
794
  return (-1 == ret ? Qfalse : Qtrue);
796
795
  }
@@ -1,188 +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
- * </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((const char*)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
- int 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
- }
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
+ }