libxml-ruby 0.5.1.0 → 0.5.2.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.
Files changed (45) hide show
  1. data/ext/xml/libxml.c +2 -1
  2. data/ext/xml/libxml.h +5 -3
  3. data/ext/xml/libxml.rb +1 -1
  4. data/ext/xml/ruby_xml_attr.c +13 -33
  5. data/ext/xml/ruby_xml_document.c +11 -22
  6. data/ext/xml/ruby_xml_document.h +2 -1
  7. data/ext/xml/ruby_xml_html_parser.c +3 -6
  8. data/ext/xml/ruby_xml_html_parser.h +1 -1
  9. data/ext/xml/ruby_xml_node.c +87 -70
  10. data/ext/xml/ruby_xml_node.h +2 -1
  11. data/ext/xml/ruby_xml_node_set.c +32 -111
  12. data/ext/xml/ruby_xml_node_set.h +5 -11
  13. data/ext/xml/ruby_xml_ns.c +1 -1
  14. data/ext/xml/ruby_xml_ns.h +1 -1
  15. data/ext/xml/ruby_xml_parser.c +11 -11
  16. data/ext/xml/ruby_xml_parser.h +1 -1
  17. data/ext/xml/ruby_xml_parser_context.c +11 -9
  18. data/ext/xml/ruby_xml_parser_context.h +1 -1
  19. data/ext/xml/ruby_xml_sax_parser.c +1 -1
  20. data/ext/xml/ruby_xml_sax_parser.h +1 -1
  21. data/ext/xml/ruby_xml_state.c +114 -0
  22. data/ext/xml/ruby_xml_state.h +11 -0
  23. data/ext/xml/ruby_xml_tree.c +1 -1
  24. data/ext/xml/ruby_xml_tree.h +1 -1
  25. data/ext/xml/ruby_xml_xinclude.c +1 -1
  26. data/ext/xml/ruby_xml_xinclude.h +1 -1
  27. data/ext/xml/ruby_xml_xpath.c +117 -231
  28. data/ext/xml/ruby_xml_xpath.h +4 -5
  29. data/ext/xml/ruby_xml_xpath_context.c +43 -50
  30. data/ext/xml/ruby_xml_xpath_context.h +3 -7
  31. data/ext/xml/ruby_xml_xpath_object.c +246 -0
  32. data/ext/xml/ruby_xml_xpath_object.h +29 -0
  33. data/ext/xml/ruby_xml_xpointer.c +8 -14
  34. data/ext/xml/ruby_xml_xpointer.h +1 -1
  35. data/ext/xml/ruby_xml_xpointer_context.c +1 -1
  36. data/ext/xml/ruby_xml_xpointer_context.h +1 -1
  37. data/ext/xml/sax_parser_callbacks.inc +1 -1
  38. data/tests/tc_xml_document.rb +5 -4
  39. data/tests/tc_xml_html_parser.rb +7 -4
  40. data/tests/tc_xml_node.rb +6 -5
  41. data/tests/tc_xml_node_set.rb +2 -2
  42. data/tests/tc_xml_node_set2.rb +3 -3
  43. data/tests/tc_xml_xpath.rb +3 -3
  44. data/tests/tc_xml_xpointer.rb +2 -2
  45. metadata +16 -10
@@ -0,0 +1,11 @@
1
+ /* $Id$ */
2
+
3
+ #ifndef __RUBY_XML_STATE__
4
+ #define __RUBY_XML_STATE__
5
+
6
+ extern VALUE cXMLState;
7
+
8
+ void ruby_xml_state_marker(void);
9
+ VALUE ruby_xml_state_object_find(VALUE id);
10
+
11
+ #endif
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_tree.c 39 2006-02-21 20:40:16Z roscopeco $ */
1
+ /* $Id: ruby_xml_tree.c 134 2007-08-29 17:30:19Z danj $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_tree.h 39 2006-02-21 20:40:16Z roscopeco $ */
1
+ /* $Id: ruby_xml_tree.h 134 2007-08-29 17:30:19Z danj $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_xinclude.c 39 2006-02-21 20:40:16Z roscopeco $ */
1
+ /* $Id: ruby_xml_xinclude.c 134 2007-08-29 17:30:19Z danj $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_xinclude.h 39 2006-02-21 20:40:16Z roscopeco $ */
1
+ /* $Id: ruby_xml_xinclude.h 134 2007-08-29 17:30:19Z danj $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -1,4 +1,4 @@
1
- /* $Id: ruby_xml_xpath.c 138 2007-08-29 18:00:35Z danj $ */
1
+ /* $Id: ruby_xml_xpath.c 192 2007-10-05 15:13:17Z danj $ */
2
2
 
3
3
  /* Please see the LICENSE file for copyright and distribution information */
4
4
 
@@ -40,37 +40,61 @@ ruby_xml_xpath_debug(VALUE self) {
40
40
  #endif
41
41
  }
42
42
 
43
- // TODO Maybe we should support [] or some other kind of access if poss.
44
-
45
- /*
46
- * call-seq:
47
- * xpath.each { |node| ... } => self
48
- *
49
- * Call the supplied block for each matching node.
50
- */
51
- VALUE
52
- ruby_xml_xpath_each(VALUE self) {
53
- ruby_xml_xpath *rxxp;
54
- VALUE rxnset;
55
-
56
- Data_Get_Struct(self, ruby_xml_xpath, rxxp);
57
-
58
- if (rxxp->xpop == NULL || rxxp->xpop->type != XPATH_NODESET)
59
- return(Qnil);
60
-
61
- rxnset = ruby_xml_node_set_new(cXMLNodeSet, rxxp->xd, self,
62
- rxxp->xpop->nodesetval);
63
- ruby_xml_node_set_each(rxnset);
64
- return(rxnset);
65
- }
66
-
67
43
  ///////////////////////////////////////////////////
68
44
  // TODO xpath_find is throwing TypeError:
69
45
  //
70
46
  // TypeError: can't convert nil into String
71
47
  //
72
48
  // When given a namespace when non exist.
49
+ void
50
+ ruby_xml_xpath_register_namespaces(VALUE nslist, VALUE xxpc, int level) {
51
+ char *cp;
52
+ long i;
53
+ VALUE rprefix, ruri;
54
+ ruby_xml_ns *rxns;
73
55
 
56
+ /* Need to loop through the 2nd argument and iterate through the
57
+ * list of namespaces that we want to allow */
58
+ switch (TYPE(nslist)) {
59
+ case T_STRING:
60
+ cp = strchr(StringValuePtr(nslist), (int)':');
61
+ if (cp == NULL) {
62
+ rprefix = nslist;
63
+ ruri = Qnil;
64
+ } else {
65
+ rprefix = rb_str_new(StringValuePtr(nslist), (int)((long)cp - (long)StringValuePtr(nslist)));
66
+ ruri = rb_str_new2(&cp[1]);
67
+ }
68
+ /* Should test the results of this */
69
+ ruby_xml_xpath_context_register_namespace(xxpc, rprefix, ruri);
70
+ break;
71
+ case T_ARRAY:
72
+ if ( level == 0 ) {
73
+ for (i = 0; i < RARRAY(nslist)->len; i++) {
74
+ ruby_xml_xpath_register_namespaces(RARRAY(nslist)->ptr[i],xxpc,1);
75
+ }
76
+ }
77
+ else {
78
+ // tuples of prefix/uri
79
+ if (RARRAY(RARRAY(nslist)->ptr[i])->len == 2) {
80
+ rprefix = RARRAY(RARRAY(nslist)->ptr[i])->ptr[0];
81
+ ruri = RARRAY(RARRAY(nslist)->ptr[i])->ptr[1];
82
+ ruby_xml_xpath_context_register_namespace(xxpc, rprefix, ruri);
83
+ } else {
84
+ rb_raise(rb_eArgError, "nested array must be an array of strings, prefix and href/uri");
85
+ }
86
+ }
87
+ break;
88
+ default:
89
+ if (rb_obj_is_kind_of(nslist, cXMLNS) == Qtrue) {
90
+ Data_Get_Struct(nslist, ruby_xml_ns, rxns);
91
+ rprefix = rb_str_new2((const char*)rxns->ns->prefix);
92
+ ruri = rb_str_new2((const char*)rxns->ns->href);
93
+ ruby_xml_xpath_context_register_namespace(xxpc, rprefix, ruri);
94
+ } else
95
+ rb_raise(rb_eArgError, "Invalid argument type, only accept string, array of strings, or an array of arrays");
96
+ }
97
+ }
74
98
  /*
75
99
  * call-seq:
76
100
  * XML::XPath.find(path, namespaces = [any]) => xpath
@@ -90,145 +114,88 @@ ruby_xml_xpath_each(VALUE self) {
90
114
  * will be included.
91
115
  */
92
116
  VALUE
93
- ruby_xml_xpath_find(int argc, VALUE *argv, VALUE class) {
117
+ ruby_xml_xpath_find(VALUE class, VALUE anode, VALUE xpath_expr, VALUE nslist) {
94
118
  #ifdef LIBXML_XPATH_ENABLED
95
119
  xmlXPathCompExprPtr comp;
120
+ xmlXPathObjectPtr xxpop;
96
121
  ruby_xml_node *node;
97
122
  ruby_xml_xpath *rxxp;
98
- ruby_xml_xpath_context *rxxpc;
99
- ruby_xml_ns *rxns;
100
- VALUE rnode, rprefix, ruri, xxpc, xpath, xpath_expr;
101
- char *cp;
102
- long i;
103
-
104
- switch(argc) {
105
- case 3:
106
- /* array of namespaces we allow.
107
- *
108
- * Accept either:
109
- * A string in the form of: "prefix:uri", or
110
- * An array of:
111
- * *) strings in the form like above
112
- * *) arrays in the form of ['prefix','uri']
113
- */
114
-
115
- /* Intentionally fall through, we deal with the last arg below
116
- * after the XPathContext object has been setup */
117
- case 2:
118
- rnode = argv[0];
119
- xpath_expr = argv[1];
120
- break;
121
- default:
122
- rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
123
- }
124
-
125
- Data_Get_Struct(rnode, ruby_xml_node, node);
126
-
127
- xxpc = ruby_xml_xpath_context_new4(rnode);
123
+ xmlXPathContextPtr ctxt;
124
+ ruby_xml_document_t *rdocp;
125
+ VALUE rnode, xxpc;
126
+ VALUE rxpop;
127
+
128
+ if (rb_obj_is_kind_of(anode, cXMLDocument) == Qtrue) {
129
+ xxpc = ruby_xml_xpath_context_new(anode);
130
+ Data_Get_Struct(anode, ruby_xml_document_t, rdocp);
131
+ #ifdef DEBUG
132
+ fprintf(stderr,"rdocp=0x%x root=0x%x\n",rdocp,xmlDocGetRootElement(rdocp->doc));
133
+ #endif
134
+ rnode=ruby_xml_node2_wrap(cXMLNode,xmlDocGetRootElement(rdocp->doc));
135
+ #ifdef DEBUG
136
+ fprintf(stderr,"rnode 0x%x 0x%x\n",rnode,xmlDocGetRootElement(rdocp->doc)->_private);
137
+ #endif
138
+ Data_Get_Struct(rnode, ruby_xml_node, node);
139
+ } else if ( rb_obj_is_kind_of(anode, cXMLNode) == Qtrue) {
140
+ xxpc = ruby_xml_xpath_context_new(anode);
141
+ Data_Get_Struct(anode, ruby_xml_node, node);
142
+ } else
143
+ rb_raise(rb_eTypeError, "arg 1 must be XML::Document or XML::Node within a document %s", rb_obj_as_string(anode));
144
+
128
145
  if (NIL_P(xxpc))
129
146
  return(Qnil);
130
- Data_Get_Struct(xxpc, ruby_xml_xpath_context, rxxpc);
131
147
 
132
- xpath = ruby_xml_xpath_new(cXMLXPath, rnode, xxpc, NULL);
133
- Data_Get_Struct(xpath, ruby_xml_xpath, rxxp);
148
+ Data_Get_Struct(xxpc,xmlXPathContext,ctxt);
149
+ // XXX Is this legal? Set a subtree to apply xpath?
150
+ ctxt->node = node->node;
134
151
 
135
- rxxpc->ctxt->node = node->node;
152
+ // XXX is setting ->namespaces used?
136
153
  if (node->node->type == XML_DOCUMENT_NODE) {
137
- rxxpc->ctxt->namespaces = xmlGetNsList(node->node->doc,
138
- xmlDocGetRootElement(node->node->doc));
154
+ ctxt->namespaces = xmlGetNsList(node->node->doc,
155
+ xmlDocGetRootElement(node->node->doc));
139
156
  } else {
140
- rxxpc->ctxt->namespaces = xmlGetNsList(node->node->doc, node->node);
157
+ ctxt->namespaces = xmlGetNsList(node->node->doc, node->node);
141
158
  }
142
159
 
143
- rxxpc->ctxt->nsNr = 0;
144
- if (rxxpc->ctxt->namespaces != NULL) {
145
- while (rxxpc->ctxt->namespaces[rxxpc->ctxt->nsNr] != NULL)
146
- rxxpc->ctxt->nsNr++;
160
+ ctxt->nsNr = 0;
161
+ if (ctxt->namespaces != NULL) {
162
+ while (ctxt->namespaces[ctxt->nsNr] != NULL)
163
+ ctxt->nsNr++;
147
164
  }
148
165
 
149
- /* Need to loop through the 2nd argument and iterate through the
150
- * list of namespaces that we want to allow */
151
- if (argc == 3) {
152
- switch (TYPE(argv[2])) {
153
- case T_STRING:
154
- cp = strchr(StringValuePtr(argv[2]), (int)':');
155
- if (cp == NULL) {
156
- rprefix = argv[2];
157
- ruri = Qnil;
158
- } else {
159
- rprefix = rb_str_new(StringValuePtr(argv[2]), (int)((long)cp - (long)StringValuePtr(argv[2])));
160
- ruri = rb_str_new2(&cp[1]);
161
- }
162
- /* Should test the results of this */
163
- ruby_xml_xpath_context_register_namespace(xxpc, rprefix, ruri);
164
- break;
165
- case T_ARRAY:
166
- for (i = 0; i < RARRAY(argv[2])->len; i++) {
167
- switch (TYPE(RARRAY(argv[2])->ptr[i])) {
168
- case T_STRING:
169
- cp = strchr(StringValuePtr(RARRAY(argv[2])->ptr[i]), (int)':');
170
- if (cp == NULL) {
171
- rprefix = RARRAY(argv[2])->ptr[i];
172
- ruri = Qnil;
173
- } else {
174
- rprefix = rb_str_new(StringValuePtr(RARRAY(argv[2])->ptr[i]), (int)((long)cp - (long)StringValuePtr(RARRAY(argv[2])->ptr[i])));
175
- ruri = rb_str_new2(&cp[1]);
176
- }
177
- /* Should test the results of this */
178
- ruby_xml_xpath_context_register_namespace(xxpc, rprefix, ruri);
179
- break;
180
- case T_ARRAY:
181
- if (RARRAY(RARRAY(argv[2])->ptr[i])->len == 2) {
182
- rprefix = RARRAY(RARRAY(argv[2])->ptr[i])->ptr[0];
183
- ruri = RARRAY(RARRAY(argv[2])->ptr[i])->ptr[1];
184
- ruby_xml_xpath_context_register_namespace(xxpc, rprefix, ruri);
185
- } else {
186
- rb_raise(rb_eArgError, "nested array must be an array of strings, prefix and href/uri");
187
- }
188
- break;
189
- default:
190
- if (rb_obj_is_kind_of(RARRAY(argv[2])->ptr[i], cXMLNS) == Qtrue) {
191
- Data_Get_Struct(argv[2], ruby_xml_ns, rxns);
192
- rprefix = rb_str_new2((const char*)rxns->ns->prefix);
193
- ruri = rb_str_new2((const char*)rxns->ns->href);
194
- ruby_xml_xpath_context_register_namespace(xxpc, rprefix, ruri);
195
- } else
196
- rb_raise(rb_eArgError, "Invalid argument type, only accept string, array of strings, or an array of arrays");
197
- }
198
- }
199
- break;
200
- default:
201
- if (rb_obj_is_kind_of(argv[2], cXMLNS) == Qtrue) {
202
- Data_Get_Struct(argv[2], ruby_xml_ns, rxns);
203
- rprefix = rb_str_new2((const char*)rxns->ns->prefix);
204
- ruri = rb_str_new2((const char*)rxns->ns->href);
205
- ruby_xml_xpath_context_register_namespace(xxpc, rprefix, ruri);
206
- } else
207
- rb_raise(rb_eArgError, "Invalid argument type, only accept string, array of strings, or an array of arrays");
208
- }
209
- }
166
+ if ( ! NIL_P(nslist) )
167
+ ruby_xml_xpath_register_namespaces(nslist,xxpc,0);
168
+
210
169
  comp = xmlXPathCompile((xmlChar*)StringValuePtr(xpath_expr));
211
170
 
212
171
  if (comp == NULL) {
213
- xmlXPathFreeCompExpr(comp);
214
- rb_raise(eXMLXPathInvalidPath, "Invalid XPath expression");
172
+ rb_raise(eXMLXPathInvalidPath,
173
+ "Invalid XPath expression (expr does not compile)");
215
174
  }
216
- rxxp->xpop = xmlXPathCompiledEval(comp, rxxpc->ctxt);
217
- xmlXPathFreeCompExpr(comp);
175
+ xxpop=xmlXPathCompiledEval(comp, ctxt);
176
+ #define ALT
177
+ #ifdef ALT
178
+ rxpop = ruby_xml_xpath_object_wrap(xxpop);
179
+ #else
180
+ rxpop = Data_Wrap_Struct(cXMLXPathObject,
181
+ ruby_xml_xpath_object_mark,
182
+ ruby_xml_xpath_object_free,
183
+ xxpop);
184
+ #endif
185
+
186
+ #ifdef NODE_DEBUG
187
+ fprintf(stderr,"xpo 0x%x class=%s\n",
188
+ rxpop,
189
+ rb_class2name(rb_obj_class(rxpop)));
190
+ #endif
218
191
 
219
- if (rxxpc->ctxt->namespaces != NULL)
220
- xmlFree(rxxpc->ctxt->namespaces);
192
+ xmlXPathFreeCompExpr(comp);
221
193
 
222
- if (rxxp->xpop == NULL)
194
+ if (rxpop == Qnil)
223
195
  rb_raise(eXMLXPathInvalidPath,
224
196
  "Invalid XPath expression for this document");
225
197
 
226
- if (rxxp->xpop->type != XPATH_NODESET)
227
- return(Qnil);
228
-
229
- return(ruby_xml_node_set_new2(ruby_xml_document_wrap(cXMLDocument,node->node->doc),
230
- xpath,
231
- rxxp->xpop->nodesetval));
198
+ return rxpop;
232
199
  #else
233
200
  rb_warn("libxml was compiled without XPath support");
234
201
  return(Qfalse);
@@ -237,95 +204,16 @@ ruby_xml_xpath_find(int argc, VALUE *argv, VALUE class) {
237
204
 
238
205
 
239
206
  VALUE
240
- ruby_xml_xpath_find2(int argc, VALUE *argv) {
241
- return(ruby_xml_xpath_find(argc, argv, cXMLXPath));
242
- }
243
-
244
-
245
- void
246
- ruby_xml_xpath_free(ruby_xml_xpath *rxxp) {
247
- if (rxxp->xpop != NULL) {
248
- xmlXPathFreeObject(rxxp->xpop);
249
- rxxp->xpop = NULL;
250
- }
251
-
252
- free(rxxp);
253
- }
254
-
255
-
256
- void
257
- ruby_xml_xpath_mark(ruby_xml_xpath *rxxp) {
258
- if (rxxp == NULL) return;
259
- if (!NIL_P(rxxp->ctxt)) rb_gc_mark(rxxp->ctxt);
260
- if (!NIL_P(rxxp->xd)) rb_gc_mark(rxxp->xd);
261
- }
262
-
263
-
264
- VALUE
265
- ruby_xml_xpath_new(VALUE class, VALUE xd, VALUE ctxt,
266
- xmlXPathObjectPtr xpop) {
267
- ruby_xml_xpath *rxxp;
268
-
269
- rxxp = ALLOC(ruby_xml_xpath);
270
- rxxp->ctxt = ctxt;
271
- rxxp->xd = xd;
272
- rxxp->xpop = xpop;
273
- return(Data_Wrap_Struct(class, ruby_xml_xpath_mark,
274
- ruby_xml_xpath_free, rxxp));
275
- }
276
-
277
-
278
- /*
279
- * call-seq:
280
- * xpath.set => nodeset
281
- *
282
- * Obtain an XML::Node::Set with nodes matching this xpath.
283
- */
284
- VALUE
285
- ruby_xml_xpath_set(VALUE self) {
286
- ruby_xml_xpath *rxxp;
287
- Data_Get_Struct(self, ruby_xml_xpath, rxxp);
288
-
289
- if (rxxp->xpop == NULL || rxxp->xpop->type != XPATH_NODESET)
290
- return(Qnil);
291
-
292
- return(ruby_xml_node_set_new(cXMLNodeSet, rxxp->xd, self,
293
- rxxp->xpop->nodesetval));
294
- }
295
-
296
-
297
- /*
298
- * call-seq:
299
- * xpath.set_type => num
300
- *
301
- * Obtains the type identifier of this xpath
302
- * set.
303
- */
304
- VALUE
305
- ruby_xml_xpath_set_type(VALUE self) {
306
- ruby_xml_xpath *rxxp;
307
- Data_Get_Struct(self, ruby_xml_xpath, rxxp);
207
+ ruby_xml_xpath_findva(int argc, VALUE *argv, VALUE class) {
208
+ if ( argc < 2 || argc > 3 )
209
+ rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)");
308
210
 
309
- return(INT2FIX(rxxp->xpop->type));
211
+ return ruby_xml_xpath_find(class,argv[0],argv[1],(argc==3)?argv[2]:Qnil);
310
212
  }
311
213
 
312
- // TODO maybe 'string' should alias as 'to_s'?
313
-
314
- /*
315
- * call-seq:
316
- * xpath.string => "xpath"
317
- *
318
- * Obtain a string representation of this xpath.
319
- */
320
214
  VALUE
321
- ruby_xml_xpath_string(VALUE self) {
322
- ruby_xml_xpath *rxxp;
323
- Data_Get_Struct(self, ruby_xml_xpath, rxxp);
324
-
325
- if (rxxp->xpop->stringval == NULL)
326
- return(Qnil);
327
- else
328
- return(rb_str_new2((const char*)rxxp->xpop->stringval));
215
+ ruby_xml_xpath_find2(VALUE anode, VALUE xpath_expr, VALUE nslist) {
216
+ return ruby_xml_xpath_find(cXMLXPath, anode, xpath_expr, nslist);
329
217
  }
330
218
 
331
219
  // Rdoc needs to know
@@ -351,13 +239,11 @@ ruby_init_xml_xpath(void) {
351
239
  rb_define_const(cXMLXPath, "USERS", INT2NUM(XPATH_USERS));
352
240
  rb_define_const(cXMLXPath, "XSLT_TREE", INT2NUM(XPATH_XSLT_TREE));
353
241
 
354
- rb_define_singleton_method(cXMLXPath, "find", ruby_xml_xpath_find, 2);
242
+ rb_define_singleton_method(cXMLXPath, "find", ruby_xml_xpath_findva, -1);
355
243
 
356
244
  rb_define_method(cXMLXPath, "debug", ruby_xml_xpath_debug, 0);
357
- rb_define_method(cXMLXPath, "each", ruby_xml_xpath_each, 0);
358
- rb_define_method(cXMLXPath, "set", ruby_xml_xpath_set, 0);
359
- rb_define_method(cXMLXPath, "set_type", ruby_xml_xpath_set_type, 0);
360
- rb_define_method(cXMLXPath, "string", ruby_xml_xpath_string, 0);
245
+
246
+ ruby_init_xml_xpath_object();
361
247
  }
362
248
 
363
249
  #endif /* ifdef LIBXML_XPATH_ENABLED */