libxml-ruby 2.8.0 → 3.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (204) hide show
  1. checksums.yaml +5 -5
  2. data/HISTORY +842 -775
  3. data/LICENSE +20 -20
  4. data/MANIFEST +166 -166
  5. data/README.rdoc +217 -184
  6. data/Rakefile +90 -78
  7. data/ext/libxml/extconf.h +3 -0
  8. data/ext/libxml/extconf.rb +61 -116
  9. data/ext/libxml/libxml.c +80 -76
  10. data/ext/libxml/ruby_libxml.h +67 -75
  11. data/ext/libxml/ruby_xml.c +933 -893
  12. data/ext/libxml/ruby_xml.h +10 -10
  13. data/ext/libxml/ruby_xml_attr.c +333 -333
  14. data/ext/libxml/ruby_xml_attr.h +12 -12
  15. data/ext/libxml/ruby_xml_attr_decl.c +153 -153
  16. data/ext/libxml/ruby_xml_attr_decl.h +11 -11
  17. data/ext/libxml/ruby_xml_attributes.c +275 -275
  18. data/ext/libxml/ruby_xml_attributes.h +15 -15
  19. data/ext/libxml/ruby_xml_cbg.c +85 -85
  20. data/ext/libxml/ruby_xml_document.c +1123 -1147
  21. data/ext/libxml/ruby_xml_document.h +11 -11
  22. data/ext/libxml/ruby_xml_dtd.c +248 -268
  23. data/ext/libxml/ruby_xml_dtd.h +9 -9
  24. data/ext/libxml/ruby_xml_encoding.c +250 -260
  25. data/ext/libxml/ruby_xml_encoding.h +16 -19
  26. data/ext/libxml/ruby_xml_error.c +996 -996
  27. data/ext/libxml/ruby_xml_error.h +12 -12
  28. data/ext/libxml/ruby_xml_html_parser.c +89 -92
  29. data/ext/libxml/ruby_xml_html_parser.h +10 -10
  30. data/ext/libxml/ruby_xml_html_parser_context.c +337 -338
  31. data/ext/libxml/ruby_xml_html_parser_context.h +10 -10
  32. data/ext/libxml/ruby_xml_html_parser_options.c +46 -46
  33. data/ext/libxml/ruby_xml_html_parser_options.h +10 -10
  34. data/ext/libxml/ruby_xml_input_cbg.c +191 -191
  35. data/ext/libxml/ruby_xml_input_cbg.h +20 -20
  36. data/ext/libxml/ruby_xml_io.c +47 -50
  37. data/ext/libxml/ruby_xml_io.h +10 -10
  38. data/ext/libxml/ruby_xml_namespace.c +153 -153
  39. data/ext/libxml/ruby_xml_namespace.h +10 -10
  40. data/ext/libxml/ruby_xml_namespaces.c +293 -293
  41. data/ext/libxml/ruby_xml_namespaces.h +9 -9
  42. data/ext/libxml/ruby_xml_node.c +1402 -1452
  43. data/ext/libxml/ruby_xml_node.h +13 -11
  44. data/ext/libxml/ruby_xml_parser.c +91 -94
  45. data/ext/libxml/ruby_xml_parser.h +12 -12
  46. data/ext/libxml/ruby_xml_parser_context.c +999 -1001
  47. data/ext/libxml/ruby_xml_parser_context.h +10 -10
  48. data/ext/libxml/ruby_xml_parser_options.c +66 -66
  49. data/ext/libxml/ruby_xml_parser_options.h +12 -12
  50. data/ext/libxml/ruby_xml_reader.c +1239 -1228
  51. data/ext/libxml/ruby_xml_reader.h +17 -17
  52. data/ext/libxml/ruby_xml_relaxng.c +110 -111
  53. data/ext/libxml/ruby_xml_relaxng.h +10 -10
  54. data/ext/libxml/ruby_xml_sax2_handler.c +326 -328
  55. data/ext/libxml/ruby_xml_sax2_handler.h +10 -10
  56. data/ext/libxml/ruby_xml_sax_parser.c +116 -120
  57. data/ext/libxml/ruby_xml_sax_parser.h +10 -10
  58. data/ext/libxml/ruby_xml_schema.c +278 -301
  59. data/ext/libxml/ruby_xml_schema.h +809 -809
  60. data/ext/libxml/ruby_xml_schema_attribute.c +109 -109
  61. data/ext/libxml/ruby_xml_schema_attribute.h +15 -15
  62. data/ext/libxml/ruby_xml_schema_element.c +95 -94
  63. data/ext/libxml/ruby_xml_schema_element.h +14 -14
  64. data/ext/libxml/ruby_xml_schema_facet.c +52 -52
  65. data/ext/libxml/ruby_xml_schema_facet.h +13 -13
  66. data/ext/libxml/ruby_xml_schema_type.c +232 -259
  67. data/ext/libxml/ruby_xml_schema_type.h +9 -9
  68. data/ext/libxml/ruby_xml_version.h +9 -9
  69. data/ext/libxml/ruby_xml_writer.c +1133 -1137
  70. data/ext/libxml/ruby_xml_writer.h +10 -10
  71. data/ext/libxml/ruby_xml_xinclude.c +16 -16
  72. data/ext/libxml/ruby_xml_xinclude.h +11 -11
  73. data/ext/libxml/ruby_xml_xpath.c +194 -188
  74. data/ext/libxml/ruby_xml_xpath.h +13 -13
  75. data/ext/libxml/ruby_xml_xpath_context.c +360 -361
  76. data/ext/libxml/ruby_xml_xpath_context.h +9 -9
  77. data/ext/libxml/ruby_xml_xpath_expression.c +81 -81
  78. data/ext/libxml/ruby_xml_xpath_expression.h +10 -10
  79. data/ext/libxml/ruby_xml_xpath_object.c +338 -335
  80. data/ext/libxml/ruby_xml_xpath_object.h +17 -17
  81. data/ext/libxml/ruby_xml_xpointer.c +99 -99
  82. data/ext/libxml/ruby_xml_xpointer.h +11 -11
  83. data/ext/vc/libxml_ruby.sln +17 -15
  84. data/lib/libxml-ruby.rb +30 -0
  85. data/lib/libxml.rb +3 -33
  86. data/lib/libxml/node.rb +2 -78
  87. data/lib/libxml/parser.rb +0 -266
  88. data/lib/libxml/sax_parser.rb +0 -17
  89. data/lib/libxml/schema.rb +47 -66
  90. data/lib/libxml/schema/attribute.rb +19 -19
  91. data/lib/libxml/schema/element.rb +19 -27
  92. data/lib/libxml/schema/type.rb +21 -29
  93. data/libxml-ruby.gemspec +48 -44
  94. data/script/benchmark/depixelate +634 -634
  95. data/script/benchmark/hamlet.xml +9054 -9054
  96. data/script/benchmark/parsecount +170 -170
  97. data/script/benchmark/throughput +41 -41
  98. data/script/test +6 -6
  99. data/setup.rb +0 -1
  100. data/test/c14n/given/example-1.xml +14 -14
  101. data/test/c14n/given/example-2.xml +11 -11
  102. data/test/c14n/given/example-3.xml +18 -18
  103. data/test/c14n/given/example-4.xml +9 -9
  104. data/test/c14n/given/example-5.xml +12 -12
  105. data/test/c14n/given/example-6.xml +2 -2
  106. data/test/c14n/given/example-7.xml +11 -11
  107. data/test/c14n/given/example-8.xml +11 -11
  108. data/test/c14n/given/example-8.xpath +9 -9
  109. data/test/c14n/result/1-1-without-comments/example-1 +3 -3
  110. data/test/c14n/result/1-1-without-comments/example-2 +10 -10
  111. data/test/c14n/result/1-1-without-comments/example-3 +13 -13
  112. data/test/c14n/result/1-1-without-comments/example-4 +8 -8
  113. data/test/c14n/result/1-1-without-comments/example-5 +2 -2
  114. data/test/c14n/result/with-comments/example-1 +5 -5
  115. data/test/c14n/result/with-comments/example-2 +10 -10
  116. data/test/c14n/result/with-comments/example-3 +13 -13
  117. data/test/c14n/result/with-comments/example-4 +8 -8
  118. data/test/c14n/result/with-comments/example-5 +3 -3
  119. data/test/c14n/result/without-comments/example-1 +3 -3
  120. data/test/c14n/result/without-comments/example-2 +10 -10
  121. data/test/c14n/result/without-comments/example-3 +13 -13
  122. data/test/c14n/result/without-comments/example-4 +8 -8
  123. data/test/c14n/result/without-comments/example-5 +2 -2
  124. data/test/model/atom.xml +12 -12
  125. data/test/model/bands.iso-8859-1.xml +4 -4
  126. data/test/model/bands.utf-8.xml +4 -4
  127. data/test/model/bands.xml +4 -4
  128. data/test/model/books.xml +153 -153
  129. data/test/model/cwm_1_0.xml +11336 -0
  130. data/test/model/merge_bug_data.xml +58 -58
  131. data/test/model/ruby-lang.html +238 -238
  132. data/test/model/rubynet.xml +79 -79
  133. data/test/model/shiporder.rnc +28 -28
  134. data/test/model/shiporder.rng +86 -86
  135. data/test/model/shiporder.xml +22 -22
  136. data/test/model/shiporder.xsd +39 -39
  137. data/test/model/soap.xml +27 -27
  138. data/test/model/xinclude.xml +4 -4
  139. data/test/test.xml +2 -0
  140. data/test/{tc_attr.rb → test_attr.rb} +23 -25
  141. data/test/{tc_attr_decl.rb → test_attr_decl.rb} +13 -14
  142. data/test/{tc_attributes.rb → test_attributes.rb} +11 -18
  143. data/test/{tc_canonicalize.rb → test_canonicalize.rb} +36 -41
  144. data/test/test_deprecated_require.rb +12 -0
  145. data/test/{tc_document.rb → test_document.rb} +32 -27
  146. data/test/test_document_write.rb +146 -0
  147. data/test/{tc_dtd.rb → test_dtd.rb} +28 -29
  148. data/test/{tc_encoding.rb → test_encoding.rb} +129 -126
  149. data/test/{tc_encoding_sax.rb → test_encoding_sax.rb} +7 -6
  150. data/test/test_error.rb +178 -0
  151. data/test/test_helper.rb +3 -10
  152. data/test/test_html_parser.rb +162 -0
  153. data/test/test_html_parser_context.rb +23 -0
  154. data/test/test_namespace.rb +60 -0
  155. data/test/{tc_namespaces.rb → test_namespaces.rb} +34 -44
  156. data/test/{tc_node.rb → test_node.rb} +68 -47
  157. data/test/{tc_node_cdata.rb → test_node_cdata.rb} +12 -13
  158. data/test/{tc_node_comment.rb → test_node_comment.rb} +7 -8
  159. data/test/{tc_node_copy.rb → test_node_copy.rb} +4 -6
  160. data/test/{tc_node_edit.rb → test_node_edit.rb} +23 -41
  161. data/test/{tc_node_pi.rb → test_node_pi.rb} +37 -40
  162. data/test/{tc_node_text.rb → test_node_text.rb} +10 -12
  163. data/test/{tc_node_write.rb → test_node_write.rb} +18 -29
  164. data/test/test_node_xlink.rb +28 -0
  165. data/test/test_parser.rb +324 -0
  166. data/test/{tc_parser_context.rb → test_parser_context.rb} +41 -42
  167. data/test/{tc_properties.rb → test_properties.rb} +6 -7
  168. data/test/test_reader.rb +363 -0
  169. data/test/test_relaxng.rb +53 -0
  170. data/test/{tc_sax_parser.rb → test_sax_parser.rb} +36 -37
  171. data/test/{tc_schema.rb → test_schema.rb} +43 -37
  172. data/test/test_suite.rb +38 -40
  173. data/test/{tc_traversal.rb → test_traversal.rb} +5 -6
  174. data/test/{tc_writer.rb → test_writer.rb} +468 -448
  175. data/test/{tc_xinclude.rb → test_xinclude.rb} +4 -5
  176. data/test/test_xml.rb +262 -0
  177. data/test/{tc_xpath.rb → test_xpath.rb} +31 -32
  178. data/test/{tc_xpath_context.rb → test_xpath_context.rb} +8 -9
  179. data/test/test_xpath_expression.rb +37 -0
  180. data/test/{tc_xpointer.rb → test_xpointer.rb} +16 -18
  181. metadata +117 -95
  182. data/lib/libxml/ns.rb +0 -22
  183. data/lib/libxml/properties.rb +0 -23
  184. data/lib/libxml/reader.rb +0 -29
  185. data/lib/libxml/xpath_object.rb +0 -16
  186. data/test/etc_doc_to_s.rb +0 -21
  187. data/test/ets_doc_file.rb +0 -17
  188. data/test/ets_doc_to_s.rb +0 -23
  189. data/test/ets_gpx.rb +0 -28
  190. data/test/ets_node_gc.rb +0 -23
  191. data/test/ets_test.xml +0 -2
  192. data/test/ets_tsr.rb +0 -11
  193. data/test/tc_deprecated_require.rb +0 -13
  194. data/test/tc_document_write.rb +0 -196
  195. data/test/tc_error.rb +0 -180
  196. data/test/tc_html_parser.rb +0 -153
  197. data/test/tc_html_parser_context.rb +0 -24
  198. data/test/tc_namespace.rb +0 -62
  199. data/test/tc_node_xlink.rb +0 -29
  200. data/test/tc_parser.rb +0 -381
  201. data/test/tc_reader.rb +0 -400
  202. data/test/tc_relaxng.rb +0 -54
  203. data/test/tc_xml.rb +0 -226
  204. data/test/tc_xpath_expression.rb +0 -38
@@ -1,10 +1,10 @@
1
- #ifndef __RXML_WRITER__
2
- #define __RXML_WRITER__
3
-
4
- #ifdef LIBXML_WRITER_ENABLED
5
- #include <libxml/xmlwriter.h>
6
- #endif
7
-
8
- extern VALUE cXMLWriter;
9
- void rxml_init_writer(void);
10
- #endif
1
+ #ifndef __RXML_WRITER__
2
+ #define __RXML_WRITER__
3
+
4
+ #ifdef LIBXML_WRITER_ENABLED
5
+ #include <libxml/xmlwriter.h>
6
+ #endif
7
+
8
+ extern VALUE cXMLWriter;
9
+ void rxml_init_writer(void);
10
+ #endif
@@ -1,16 +1,16 @@
1
- #include "ruby_libxml.h"
2
- #include "ruby_xml_xinclude.h"
3
-
4
- VALUE cXMLXInclude;
5
-
6
- /*
7
- * Document-class: LibXML::XML::XInclude
8
- *
9
- * The ruby bindings do not currently expose libxml's
10
- * XInclude fuctionality.
11
- */
12
-
13
- void rxml_init_xinclude(void)
14
- {
15
- cXMLXInclude = rb_define_class_under(mXML, "XInclude", rb_cObject);
16
- }
1
+ #include "ruby_libxml.h"
2
+ #include "ruby_xml_xinclude.h"
3
+
4
+ VALUE cXMLXInclude;
5
+
6
+ /*
7
+ * Document-class: LibXML::XML::XInclude
8
+ *
9
+ * The ruby bindings do not currently expose libxml's
10
+ * XInclude fuctionality.
11
+ */
12
+
13
+ void rxml_init_xinclude(void)
14
+ {
15
+ cXMLXInclude = rb_define_class_under(mXML, "XInclude", rb_cObject);
16
+ }
@@ -1,11 +1,11 @@
1
- /* Please see the LICENSE file for copyright and distribution information */
2
-
3
- #ifndef __RXML_XINCLUDE__
4
- #define __RXML_XINCLUDE__
5
-
6
- extern VALUE cXMLXInclude;
7
- extern VALUE eXMLXIncludeError;
8
-
9
- void rxml_init_xinclude(void);
10
-
11
- #endif
1
+ /* Please see the LICENSE file for copyright and distribution information */
2
+
3
+ #ifndef __RXML_XINCLUDE__
4
+ #define __RXML_XINCLUDE__
5
+
6
+ extern VALUE cXMLXInclude;
7
+ extern VALUE eXMLXIncludeError;
8
+
9
+ void rxml_init_xinclude(void);
10
+
11
+ #endif
@@ -1,188 +1,194 @@
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
+ #include "ruby_libxml.h"
78
+
79
+ VALUE mXPath;
80
+
81
+ VALUE rxml_xpath_to_value(xmlXPathContextPtr xctxt, xmlXPathObjectPtr xobject)
82
+ {
83
+ VALUE result;
84
+ int type;
85
+
86
+ if (xobject == NULL)
87
+ {
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
+ {
97
+ case XPATH_NODESET:
98
+ result = rxml_xpath_object_wrap(xctxt->doc, xobject);
99
+ break;
100
+ case XPATH_BOOLEAN:
101
+ result = (xobject->boolval != 0) ? Qtrue : Qfalse;
102
+ xmlXPathFreeObject(xobject);
103
+ break;
104
+ case XPATH_NUMBER:
105
+ result = rb_float_new(xobject->floatval);
106
+ xmlXPathFreeObject(xobject);
107
+ break;
108
+ case XPATH_STRING:
109
+ result = rxml_new_cstr(xobject->stringval, xctxt->doc->encoding);
110
+ xmlXPathFreeObject(xobject);
111
+ break;
112
+ default:
113
+ xmlXPathFreeObject(xobject);
114
+ rb_raise(rb_eTypeError,
115
+ "can't convert XPath object of type %d to Ruby value", type
116
+ );
117
+ }
118
+
119
+ return result;
120
+ }
121
+
122
+ xmlXPathObjectPtr rxml_xpath_from_value(VALUE value)
123
+ {
124
+ xmlXPathObjectPtr result = NULL;
125
+
126
+ switch (TYPE(value))
127
+ {
128
+ case T_TRUE:
129
+ case T_FALSE:
130
+ result = xmlXPathNewBoolean(RTEST(value));
131
+ break;
132
+ case T_FIXNUM:
133
+ case T_FLOAT:
134
+ result = xmlXPathNewFloat(NUM2DBL(value));
135
+ break;
136
+ case T_STRING:
137
+ result = xmlXPathWrapString(xmlStrdup((const xmlChar *)StringValuePtr(value)));
138
+ break;
139
+ case T_NIL:
140
+ result = xmlXPathNewNodeSet(NULL);
141
+ break;
142
+ case T_ARRAY:
143
+ {
144
+ long i, j;
145
+ result = xmlXPathNewNodeSet(NULL);
146
+
147
+ for (i = RARRAY_LEN(value); i > 0; i--)
148
+ {
149
+ xmlXPathObjectPtr obj = rxml_xpath_from_value(rb_ary_shift(value));
150
+
151
+ if ((obj->nodesetval != NULL) && (obj->nodesetval->nodeNr != 0))
152
+ {
153
+ for (j = 0; j < obj->nodesetval->nodeNr; j++)
154
+ {
155
+ xmlXPathNodeSetAdd(result->nodesetval, obj->nodesetval->nodeTab[j]);
156
+ }
157
+ }
158
+ }
159
+ break;
160
+ }
161
+ default:
162
+ rb_raise(rb_eTypeError,
163
+ "can't convert object of type %s to XPath object", rb_obj_classname(value)
164
+ );
165
+ }
166
+
167
+ return result;
168
+ }
169
+
170
+ void rxml_init_xpath(void)
171
+ {
172
+ mXPath = rb_define_module_under(mXML, "XPath");
173
+
174
+ /* 0: Undefined value. */
175
+ rb_define_const(mXPath, "UNDEFINED", INT2NUM(XPATH_UNDEFINED));
176
+ /* 1: A nodeset, will be wrapped by XPath Object. */
177
+ rb_define_const(mXPath, "NODESET", INT2NUM(XPATH_NODESET));
178
+ /* 2: A boolean value. */
179
+ rb_define_const(mXPath, "BOOLEAN", INT2NUM(XPATH_BOOLEAN));
180
+ /* 3: A numeric value. */
181
+ rb_define_const(mXPath, "NUMBER", INT2NUM(XPATH_NUMBER));
182
+ /* 4: A string value. */
183
+ rb_define_const(mXPath, "STRING", INT2NUM(XPATH_STRING));
184
+ /* 5: An xpointer point */
185
+ rb_define_const(mXPath, "POINT", INT2NUM(XPATH_POINT));
186
+ /* 6: An xpointer range */
187
+ rb_define_const(mXPath, "RANGE", INT2NUM(XPATH_RANGE));
188
+ /* 7: An xpointer location set */
189
+ rb_define_const(mXPath, "LOCATIONSET", INT2NUM(XPATH_LOCATIONSET));
190
+ /* 8: XPath user type */
191
+ rb_define_const(mXPath, "USERS", INT2NUM(XPATH_USERS));
192
+ /* 9: An XSLT value tree, non modifiable */
193
+ rb_define_const(mXPath, "XSLT_TREE", INT2NUM(XPATH_XSLT_TREE));
194
+ }