nokogiri 1.14.5 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nokogiri might be problematic. Click here for more details.

Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +9 -8
  3. data/dependencies.yml +6 -6
  4. data/ext/nokogiri/extconf.rb +66 -22
  5. data/ext/nokogiri/html4_document.c +1 -2
  6. data/ext/nokogiri/html4_element_description.c +19 -14
  7. data/ext/nokogiri/html4_sax_parser_context.c +10 -16
  8. data/ext/nokogiri/html4_sax_push_parser.c +2 -2
  9. data/ext/nokogiri/nokogiri.c +46 -24
  10. data/ext/nokogiri/nokogiri.h +13 -2
  11. data/ext/nokogiri/xml_attr.c +1 -1
  12. data/ext/nokogiri/xml_cdata.c +10 -2
  13. data/ext/nokogiri/xml_comment.c +1 -1
  14. data/ext/nokogiri/xml_document.c +102 -22
  15. data/ext/nokogiri/xml_document_fragment.c +1 -1
  16. data/ext/nokogiri/xml_dtd.c +1 -1
  17. data/ext/nokogiri/xml_element_content.c +32 -29
  18. data/ext/nokogiri/xml_element_decl.c +5 -5
  19. data/ext/nokogiri/xml_encoding_handler.c +12 -4
  20. data/ext/nokogiri/xml_entity_reference.c +1 -1
  21. data/ext/nokogiri/xml_namespace.c +11 -12
  22. data/ext/nokogiri/xml_node.c +7 -7
  23. data/ext/nokogiri/xml_node_set.c +125 -105
  24. data/ext/nokogiri/xml_processing_instruction.c +1 -1
  25. data/ext/nokogiri/xml_reader.c +37 -28
  26. data/ext/nokogiri/xml_relax_ng.c +65 -78
  27. data/ext/nokogiri/xml_sax_parser.c +24 -5
  28. data/ext/nokogiri/xml_sax_parser_context.c +46 -25
  29. data/ext/nokogiri/xml_sax_push_parser.c +29 -8
  30. data/ext/nokogiri/xml_schema.c +90 -116
  31. data/ext/nokogiri/xml_text.c +10 -2
  32. data/ext/nokogiri/xml_xpath_context.c +156 -83
  33. data/ext/nokogiri/xslt_stylesheet.c +103 -50
  34. data/gumbo-parser/src/error.c +8 -4
  35. data/gumbo-parser/src/foreign_attrs.c +13 -14
  36. data/gumbo-parser/src/foreign_attrs.gperf +1 -1
  37. data/gumbo-parser/src/parser.c +13 -0
  38. data/lib/nokogiri/css/xpath_visitor.rb +2 -2
  39. data/lib/nokogiri/extension.rb +1 -1
  40. data/lib/nokogiri/html4/document_fragment.rb +1 -1
  41. data/lib/nokogiri/html4/element_description_defaults.rb +1821 -353
  42. data/lib/nokogiri/html5/document_fragment.rb +1 -1
  43. data/lib/nokogiri/html5/node.rb +5 -0
  44. data/lib/nokogiri/html5.rb +5 -2
  45. data/lib/nokogiri/jruby/nokogiri_jars.rb +3 -3
  46. data/lib/nokogiri/version/constant.rb +1 -1
  47. data/lib/nokogiri/xml/attribute_decl.rb +4 -2
  48. data/lib/nokogiri/xml/document_fragment.rb +1 -1
  49. data/lib/nokogiri/xml/element_content.rb +10 -2
  50. data/lib/nokogiri/xml/element_decl.rb +4 -2
  51. data/lib/nokogiri/xml/entity_decl.rb +4 -2
  52. data/lib/nokogiri/xml/node/save_options.rb +8 -0
  53. data/lib/nokogiri/xml/node.rb +22 -13
  54. data/lib/nokogiri/xml/pp/node.rb +23 -12
  55. data/lib/nokogiri/xml/sax/document.rb +1 -1
  56. data/lib/nokogiri/xml/searchable.rb +18 -10
  57. data/lib/nokogiri/xslt.rb +73 -3
  58. data/lib/nokogiri.rb +12 -4
  59. data/lib/xsd/xmlparser/nokogiri.rb +1 -1
  60. data/patches/libxml2/0010-update-config.guess-and-config.sub-for-libxml2.patch +224 -0
  61. data/patches/libxml2/0011-rip-out-libxml2-s-libc_single_threaded-support.patch +30 -0
  62. data/patches/libxslt/0001-update-config.guess-and-config.sub-for-libxslt.patch +224 -0
  63. data/ports/archives/libxml2-2.11.3.tar.xz +0 -0
  64. data/ports/archives/libxslt-1.1.38.tar.xz +0 -0
  65. metadata +9 -7
  66. data/patches/libxslt/0001-update-automake-files-for-arm64.patch +0 -3037
  67. data/ports/archives/libxml2-2.10.4.tar.xz +0 -0
  68. data/ports/archives/libxslt-1.1.37.tar.xz +0 -0
@@ -12,11 +12,20 @@ static const xmlChar *NOKOGIRI_BUILTIN_PREFIX = (const xmlChar *)"nokogiri-built
12
12
  static const xmlChar *NOKOGIRI_BUILTIN_URI = (const xmlChar *)"https://www.nokogiri.org/default_ns/ruby/builtins";
13
13
 
14
14
  static void
15
- xml_xpath_context_deallocate(xmlXPathContextPtr ctx)
15
+ xml_xpath_context_deallocate(void *data)
16
16
  {
17
- xmlXPathFreeContext(ctx);
17
+ xmlXPathContextPtr c_context = data;
18
+ xmlXPathFreeContext(c_context);
18
19
  }
19
20
 
21
+ static const rb_data_type_t xml_xpath_context_type = {
22
+ .wrap_struct_name = "Nokogiri::XML::XPathContext",
23
+ .function = {
24
+ .dfree = xml_xpath_context_deallocate,
25
+ },
26
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
27
+ };
28
+
20
29
  /* find a CSS class in an HTML element's `class` attribute */
21
30
  static const xmlChar *
22
31
  builtin_css_class(const xmlChar *str, const xmlChar *val)
@@ -87,7 +96,8 @@ xpath_builtin_css_class(xmlXPathParserContextPtr ctxt, int nargs)
87
96
  }
88
97
 
89
98
 
90
- /* xmlXPathFunction to select nodes whose local name matches, for HTML5 CSS queries that should ignore namespaces */
99
+ /* xmlXPathFunction to select nodes whose local name matches, for HTML5 CSS queries that should
100
+ * ignore namespaces */
91
101
  static void
92
102
  xpath_builtin_local_name_is(xmlXPathParserContextPtr ctxt, int nargs)
93
103
  {
@@ -100,7 +110,10 @@ xpath_builtin_local_name_is(xmlXPathParserContextPtr ctxt, int nargs)
100
110
  CHECK_TYPE(XPATH_STRING);
101
111
  element_name = valuePop(ctxt);
102
112
 
103
- valuePush(ctxt, xmlXPathNewBoolean(xmlStrEqual(ctxt->context->node->name, element_name->stringval)));
113
+ valuePush(
114
+ ctxt,
115
+ xmlXPathNewBoolean(xmlStrEqual(ctxt->context->node->name, element_name->stringval))
116
+ );
104
117
 
105
118
  xmlXPathFreeObject(element_name);
106
119
  }
@@ -108,44 +121,61 @@ xpath_builtin_local_name_is(xmlXPathParserContextPtr ctxt, int nargs)
108
121
 
109
122
  /*
110
123
  * call-seq:
111
- * register_ns(prefix, uri)
124
+ * register_ns(prefix, uri) → Nokogiri::XML::XPathContext
125
+ *
126
+ * Register the namespace with +prefix+ and +uri+ for use in future queries.
112
127
  *
113
- * Register the namespace with +prefix+ and +uri+.
128
+ * [Returns] +self+
114
129
  */
115
130
  static VALUE
116
- rb_xml_xpath_context_register_ns(VALUE self, VALUE prefix, VALUE uri)
131
+ rb_xml_xpath_context_register_ns(VALUE rb_context, VALUE prefix, VALUE uri)
117
132
  {
118
- xmlXPathContextPtr ctx;
119
- Data_Get_Struct(self, xmlXPathContext, ctx);
133
+ xmlXPathContextPtr c_context;
134
+
135
+ TypedData_Get_Struct(
136
+ rb_context,
137
+ xmlXPathContext,
138
+ &xml_xpath_context_type,
139
+ c_context
140
+ );
120
141
 
121
- xmlXPathRegisterNs(ctx,
142
+ xmlXPathRegisterNs(c_context,
122
143
  (const xmlChar *)StringValueCStr(prefix),
123
144
  (const xmlChar *)StringValueCStr(uri)
124
145
  );
125
- return self;
146
+ return rb_context;
126
147
  }
127
148
 
128
149
  /*
129
150
  * call-seq:
130
- * register_variable(name, value)
151
+ * register_variable(name, value) → Nokogiri::XML::XPathContext
131
152
  *
132
- * Register the variable +name+ with +value+.
153
+ * Register the variable +name+ with +value+ for use in future queries.
154
+ *
155
+ * [Returns] +self+
133
156
  */
134
157
  static VALUE
135
- rb_xml_xpath_context_register_variable(VALUE self, VALUE name, VALUE value)
158
+ rb_xml_xpath_context_register_variable(VALUE rb_context, VALUE name, VALUE value)
136
159
  {
137
- xmlXPathContextPtr ctx;
160
+ xmlXPathContextPtr c_context;
138
161
  xmlXPathObjectPtr xmlValue;
139
- Data_Get_Struct(self, xmlXPathContext, ctx);
162
+
163
+ TypedData_Get_Struct(
164
+ rb_context,
165
+ xmlXPathContext,
166
+ &xml_xpath_context_type,
167
+ c_context
168
+ );
140
169
 
141
170
  xmlValue = xmlXPathNewCString(StringValueCStr(value));
142
171
 
143
- xmlXPathRegisterVariable(ctx,
144
- (const xmlChar *)StringValueCStr(name),
145
- xmlValue
146
- );
172
+ xmlXPathRegisterVariable(
173
+ c_context,
174
+ (const xmlChar *)StringValueCStr(name),
175
+ xmlValue
176
+ );
147
177
 
148
- return self;
178
+ return rb_context;
149
179
  }
150
180
 
151
181
 
@@ -154,12 +184,12 @@ rb_xml_xpath_context_register_variable(VALUE self, VALUE name, VALUE value)
154
184
  * returns Qundef if no conversion was possible.
155
185
  */
156
186
  static VALUE
157
- xpath2ruby(xmlXPathObjectPtr c_xpath_object, xmlXPathContextPtr ctx)
187
+ xpath2ruby(xmlXPathObjectPtr c_xpath_object, xmlXPathContextPtr c_context)
158
188
  {
159
189
  VALUE rb_retval;
160
190
 
161
- assert(ctx->doc);
162
- assert(DOC_RUBY_OBJECT_TEST(ctx->doc));
191
+ assert(c_context->doc);
192
+ assert(DOC_RUBY_OBJECT_TEST(c_context->doc));
163
193
 
164
194
  switch (c_xpath_object->type) {
165
195
  case XPATH_STRING:
@@ -168,8 +198,10 @@ xpath2ruby(xmlXPathObjectPtr c_xpath_object, xmlXPathContextPtr ctx)
168
198
  return rb_retval;
169
199
 
170
200
  case XPATH_NODESET:
171
- return noko_xml_node_set_wrap(c_xpath_object->nodesetval,
172
- DOC_RUBY_OBJECT(ctx->doc));
201
+ return noko_xml_node_set_wrap(
202
+ c_xpath_object->nodesetval,
203
+ DOC_RUBY_OBJECT(c_context->doc)
204
+ );
173
205
 
174
206
  case XPATH_NUMBER:
175
207
  return rb_float_new(c_xpath_object->floatval);
@@ -184,7 +216,7 @@ xpath2ruby(xmlXPathObjectPtr c_xpath_object, xmlXPathContextPtr ctx)
184
216
 
185
217
  void
186
218
  Nokogiri_marshal_xpath_funcall_and_return_values(
187
- xmlXPathParserContextPtr ctx,
219
+ xmlXPathParserContextPtr ctxt,
188
220
  int argc,
189
221
  VALUE rb_xpath_handler,
190
222
  const char *method_name
@@ -196,8 +228,8 @@ Nokogiri_marshal_xpath_funcall_and_return_values(
196
228
  xmlNodeSetPtr c_node_set = NULL;
197
229
  xmlXPathObjectPtr c_xpath_object;
198
230
 
199
- assert(ctx->context->doc);
200
- assert(DOC_RUBY_OBJECT_TEST(ctx->context->doc));
231
+ assert(ctxt->context->doc);
232
+ assert(DOC_RUBY_OBJECT_TEST(ctxt->context->doc));
201
233
 
202
234
  argv = (VALUE *)ruby_xcalloc((size_t)argc, sizeof(VALUE));
203
235
  for (int j = 0 ; j < argc ; ++j) {
@@ -205,15 +237,20 @@ Nokogiri_marshal_xpath_funcall_and_return_values(
205
237
  }
206
238
 
207
239
  for (int j = argc - 1 ; j >= 0 ; --j) {
208
- c_xpath_object = valuePop(ctx);
209
- argv[j] = xpath2ruby(c_xpath_object, ctx->context);
240
+ c_xpath_object = valuePop(ctxt);
241
+ argv[j] = xpath2ruby(c_xpath_object, ctxt->context);
210
242
  if (argv[j] == Qundef) {
211
243
  argv[j] = NOKOGIRI_STR_NEW2(xmlXPathCastToString(c_xpath_object));
212
244
  }
213
245
  xmlXPathFreeNodeSetList(c_xpath_object);
214
246
  }
215
247
 
216
- rb_retval = rb_funcall2(rb_xpath_handler, rb_intern((const char *)method_name), argc, argv);
248
+ rb_retval = rb_funcall2(
249
+ rb_xpath_handler,
250
+ rb_intern((const char *)method_name),
251
+ argc,
252
+ argv
253
+ );
217
254
 
218
255
  for (int j = 0 ; j < argc ; ++j) {
219
256
  rb_gc_unregister_address(&argv[j]);
@@ -224,31 +261,31 @@ Nokogiri_marshal_xpath_funcall_and_return_values(
224
261
  case T_FLOAT:
225
262
  case T_BIGNUM:
226
263
  case T_FIXNUM:
227
- xmlXPathReturnNumber(ctx, NUM2DBL(rb_retval));
264
+ xmlXPathReturnNumber(ctxt, NUM2DBL(rb_retval));
228
265
  break;
229
266
  case T_STRING:
230
- xmlXPathReturnString(ctx, xmlCharStrdup(StringValueCStr(rb_retval)));
267
+ xmlXPathReturnString(ctxt, xmlCharStrdup(StringValueCStr(rb_retval)));
231
268
  break;
232
269
  case T_TRUE:
233
- xmlXPathReturnTrue(ctx);
270
+ xmlXPathReturnTrue(ctxt);
234
271
  break;
235
272
  case T_FALSE:
236
- xmlXPathReturnFalse(ctx);
273
+ xmlXPathReturnFalse(ctxt);
237
274
  break;
238
275
  case T_NIL:
239
276
  break;
240
277
  case T_ARRAY: {
241
- VALUE construct_args[2] = { DOC_RUBY_OBJECT(ctx->context->doc), rb_retval };
278
+ VALUE construct_args[2] = { DOC_RUBY_OBJECT(ctxt->context->doc), rb_retval };
242
279
  rb_node_set = rb_class_new_instance(2, construct_args, cNokogiriXmlNodeSet);
243
- Data_Get_Struct(rb_node_set, xmlNodeSet, c_node_set);
244
- xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, c_node_set));
280
+ c_node_set = noko_xml_node_set_unwrap(rb_node_set);
281
+ xmlXPathReturnNodeSet(ctxt, xmlXPathNodeSetMerge(NULL, c_node_set));
245
282
  }
246
283
  break;
247
284
  case T_DATA:
248
285
  if (rb_obj_is_kind_of(rb_retval, cNokogiriXmlNodeSet)) {
249
- Data_Get_Struct(rb_retval, xmlNodeSet, c_node_set);
286
+ c_node_set = noko_xml_node_set_unwrap(rb_retval);
250
287
  /* Copy the node set, otherwise it will get GC'd. */
251
- xmlXPathReturnNodeSet(ctx, xmlXPathNodeSetMerge(NULL, c_node_set));
288
+ xmlXPathReturnNodeSet(ctxt, xmlXPathNodeSetMerge(NULL, c_node_set));
252
289
  break;
253
290
  }
254
291
  default:
@@ -257,27 +294,39 @@ Nokogiri_marshal_xpath_funcall_and_return_values(
257
294
  }
258
295
 
259
296
  static void
260
- method_caller(xmlXPathParserContextPtr ctx, int argc)
297
+ method_caller(xmlXPathParserContextPtr ctxt, int argc)
261
298
  {
262
299
  VALUE rb_xpath_handler = Qnil;
263
300
  const char *method_name = NULL ;
264
301
 
265
- assert(ctx);
266
- assert(ctx->context);
267
- assert(ctx->context->userData);
268
- assert(ctx->context->function);
302
+ assert(ctxt);
303
+ assert(ctxt->context);
304
+ assert(ctxt->context->userData);
305
+ assert(ctxt->context->function);
269
306
 
270
- rb_xpath_handler = (VALUE)(ctx->context->userData);
271
- method_name = (const char *)(ctx->context->function);
307
+ rb_xpath_handler = (VALUE)(ctxt->context->userData);
308
+ method_name = (const char *)(ctxt->context->function);
272
309
 
273
- Nokogiri_marshal_xpath_funcall_and_return_values(ctx, argc, rb_xpath_handler, method_name);
310
+ Nokogiri_marshal_xpath_funcall_and_return_values(
311
+ ctxt,
312
+ argc,
313
+ rb_xpath_handler,
314
+ method_name
315
+ );
274
316
  }
275
317
 
276
318
  static xmlXPathFunction
277
- handler_lookup(void *ctx, const xmlChar *c_name, const xmlChar *c_ns_uri)
319
+ handler_lookup(void *data, const xmlChar *c_name, const xmlChar *c_ns_uri)
278
320
  {
279
- VALUE rb_xpath_handler = (VALUE)ctx;
280
- if (rb_respond_to(rb_xpath_handler, rb_intern((const char *)c_name))) {
321
+ VALUE rb_handler = (VALUE)data;
322
+ if (rb_respond_to(rb_handler, rb_intern((const char *)c_name))) {
323
+ if (c_ns_uri == NULL) {
324
+ NOKO_WARN_DEPRECATION(
325
+ "A custom XPath or CSS handler function named '%s' is being invoked without a namespace."
326
+ " Please update your query to reference this function as 'nokogiri:%s'."
327
+ " Invoking custom handler functions without a namespace is deprecated and support will be removed in a future release of Nokogiri.",
328
+ c_name, c_name);
329
+ }
281
330
  return method_caller;
282
331
  }
283
332
 
@@ -286,9 +335,9 @@ handler_lookup(void *ctx, const xmlChar *c_name, const xmlChar *c_ns_uri)
286
335
 
287
336
  PRINTFLIKE_DECL(2, 3)
288
337
  static void
289
- generic_exception_pusher(void *ctx, const char *msg, ...)
338
+ generic_exception_pusher(void *data, const char *msg, ...)
290
339
  {
291
- VALUE rb_errors = (VALUE)ctx;
340
+ VALUE rb_errors = (VALUE)data;
292
341
  VALUE rb_message;
293
342
  VALUE rb_exception;
294
343
 
@@ -311,21 +360,29 @@ generic_exception_pusher(void *ctx, const char *msg, ...)
311
360
 
312
361
  /*
313
362
  * call-seq:
314
- * evaluate(search_path, handler = nil)
363
+ * evaluate(search_path, handler = nil) → Object
364
+ *
365
+ * Evaluate the +search_path+ query.
315
366
  *
316
- * Evaluate the +search_path+ returning an XML::XPath object.
367
+ * [Returns] an object of the appropriate type for the query, which could be +NodeSet+, a +String+,
368
+ * a +Float+, or a boolean.
317
369
  */
318
370
  static VALUE
319
- rb_xml_xpath_context_evaluate(int argc, VALUE *argv, VALUE self)
371
+ rb_xml_xpath_context_evaluate(int argc, VALUE *argv, VALUE rb_context)
320
372
  {
321
373
  VALUE search_path, xpath_handler;
322
374
  VALUE retval = Qnil;
323
- xmlXPathContextPtr ctx;
375
+ xmlXPathContextPtr c_context;
324
376
  xmlXPathObjectPtr xpath;
325
377
  xmlChar *query;
326
378
  VALUE errors = rb_ary_new();
327
379
 
328
- Data_Get_Struct(self, xmlXPathContext, ctx);
380
+ TypedData_Get_Struct(
381
+ rb_context,
382
+ xmlXPathContext,
383
+ &xml_xpath_context_type,
384
+ c_context
385
+ );
329
386
 
330
387
  if (rb_scan_args(argc, argv, "11", &search_path, &xpath_handler) == 1) {
331
388
  xpath_handler = Qnil;
@@ -335,14 +392,18 @@ rb_xml_xpath_context_evaluate(int argc, VALUE *argv, VALUE self)
335
392
 
336
393
  if (Qnil != xpath_handler) {
337
394
  /* FIXME: not sure if this is the correct place to shove private data. */
338
- ctx->userData = (void *)xpath_handler;
339
- xmlXPathRegisterFuncLookup(ctx, handler_lookup, (void *)xpath_handler);
395
+ c_context->userData = (void *)xpath_handler;
396
+ xmlXPathRegisterFuncLookup(
397
+ c_context,
398
+ handler_lookup,
399
+ (void *)xpath_handler
400
+ );
340
401
  }
341
402
 
342
403
  xmlSetStructuredErrorFunc((void *)errors, Nokogiri_error_array_pusher);
343
404
  xmlSetGenericErrorFunc((void *)errors, generic_exception_pusher);
344
405
 
345
- xpath = xmlXPathEvalExpression(query, ctx);
406
+ xpath = xmlXPathEvalExpression(query, c_context);
346
407
 
347
408
  xmlSetStructuredErrorFunc(NULL, NULL);
348
409
  xmlSetGenericErrorFunc(NULL, NULL);
@@ -351,9 +412,9 @@ rb_xml_xpath_context_evaluate(int argc, VALUE *argv, VALUE self)
351
412
  rb_exc_raise(rb_ary_entry(errors, 0));
352
413
  }
353
414
 
354
- retval = xpath2ruby(xpath, ctx);
415
+ retval = xpath2ruby(xpath, c_context);
355
416
  if (retval == Qundef) {
356
- retval = noko_xml_node_set_wrap(NULL, DOC_RUBY_OBJECT(ctx->doc));
417
+ retval = noko_xml_node_set_wrap(NULL, DOC_RUBY_OBJECT(c_context->doc));
357
418
  }
358
419
 
359
420
  xmlXPathFreeNodeSetList(xpath);
@@ -363,43 +424,55 @@ rb_xml_xpath_context_evaluate(int argc, VALUE *argv, VALUE self)
363
424
 
364
425
  /*
365
426
  * call-seq:
366
- * new(node)
427
+ * new(node)
367
428
  *
368
- * Create a new XPathContext with +node+ as the reference point.
429
+ * Create a new XPathContext with +node+ as the context node.
369
430
  */
370
431
  static VALUE
371
- rb_xml_xpath_context_new(VALUE klass, VALUE nodeobj)
432
+ rb_xml_xpath_context_new(VALUE klass, VALUE rb_node)
372
433
  {
373
434
  xmlNodePtr node;
374
- xmlXPathContextPtr ctx;
375
- VALUE self;
435
+ xmlXPathContextPtr c_context;
436
+ VALUE rb_context;
376
437
 
377
- Noko_Node_Get_Struct(nodeobj, xmlNode, node);
438
+ Noko_Node_Get_Struct(rb_node, xmlNode, node);
378
439
 
379
440
  #if LIBXML_VERSION < 21000
380
441
  /* deprecated in 40483d0 */
381
442
  xmlXPathInit();
382
443
  #endif
383
444
 
384
- ctx = xmlXPathNewContext(node->doc);
385
- ctx->node = node;
386
-
387
- xmlXPathRegisterNs(ctx, NOKOGIRI_PREFIX, NOKOGIRI_URI);
388
- xmlXPathRegisterNs(ctx, NOKOGIRI_BUILTIN_PREFIX, NOKOGIRI_BUILTIN_URI);
389
- xmlXPathRegisterFuncNS(ctx, (const xmlChar *)"css-class", NOKOGIRI_BUILTIN_URI,
390
- xpath_builtin_css_class);
391
- xmlXPathRegisterFuncNS(ctx, (const xmlChar *)"local-name-is", NOKOGIRI_BUILTIN_URI,
392
- xpath_builtin_local_name_is);
393
-
394
- self = Data_Wrap_Struct(klass, 0, xml_xpath_context_deallocate, ctx);
395
- return self;
445
+ c_context = xmlXPathNewContext(node->doc);
446
+ c_context->node = node;
447
+
448
+ xmlXPathRegisterNs(c_context, NOKOGIRI_PREFIX, NOKOGIRI_URI);
449
+ xmlXPathRegisterNs(c_context, NOKOGIRI_BUILTIN_PREFIX, NOKOGIRI_BUILTIN_URI);
450
+ xmlXPathRegisterFuncNS(
451
+ c_context,
452
+ (const xmlChar *)"css-class",
453
+ NOKOGIRI_BUILTIN_URI,
454
+ xpath_builtin_css_class
455
+ );
456
+ xmlXPathRegisterFuncNS(
457
+ c_context,
458
+ (const xmlChar *)"local-name-is",
459
+ NOKOGIRI_BUILTIN_URI,
460
+ xpath_builtin_local_name_is
461
+ );
462
+
463
+ rb_context = TypedData_Wrap_Struct(
464
+ klass,
465
+ &xml_xpath_context_type,
466
+ c_context
467
+ );
468
+ return rb_context;
396
469
  }
397
470
 
398
471
  void
399
472
  noko_init_xml_xpath_context(void)
400
473
  {
401
474
  /*
402
- * XPathContext is the entry point for searching a Document by using XPath.
475
+ * XPathContext is the entry point for searching a +Document+ by using XPath.
403
476
  */
404
477
  cNokogiriXmlXpathContext = rb_define_class_under(mNokogiriXml, "XPathContext", rb_cObject);
405
478