Class: Nokogiri::XML::XPathContext

Inherits:
Object
  • Object
show all
Defined in:
lib/nokogiri/xml/xpath_context.rb,
ext/nokogiri/xml_xpath_context.c

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.new(node) ⇒ Object

Create a new XPathContext with node as the context node.



428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
# File 'ext/nokogiri/xml_xpath_context.c', line 428

static VALUE
rb_xml_xpath_context_new(VALUE klass, VALUE rb_node)
{
  xmlNodePtr node;
  xmlXPathContextPtr c_context;
  VALUE rb_context;

  Noko_Node_Get_Struct(rb_node, xmlNode, node);

#if LIBXML_VERSION < 21000
  /* deprecated in 40483d0 */
  xmlXPathInit();
#endif

  c_context = xmlXPathNewContext(node->doc);
  c_context->node = node;

  xmlXPathRegisterNs(c_context, NOKOGIRI_PREFIX, NOKOGIRI_URI);
  xmlXPathRegisterNs(c_context, NOKOGIRI_BUILTIN_PREFIX, NOKOGIRI_BUILTIN_URI);
  xmlXPathRegisterFuncNS(
    c_context,
    (const xmlChar *)"css-class",
    NOKOGIRI_BUILTIN_URI,
    xpath_builtin_css_class
  );
  xmlXPathRegisterFuncNS(
    c_context,
    (const xmlChar *)"local-name-is",
    NOKOGIRI_BUILTIN_URI,
    xpath_builtin_local_name_is
  );

  rb_context = TypedData_Wrap_Struct(
                 klass,
                 &xml_xpath_context_type,
                 c_context
               );
  return rb_context;
}

Instance Method Details

#evaluate(search_path, handler = nil) ⇒ Object

Evaluate the search_path query.

Returns

an object of the appropriate type for the query, which could be NodeSet, a String,

a Float, or a boolean.



367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
# File 'ext/nokogiri/xml_xpath_context.c', line 367

static VALUE
rb_xml_xpath_context_evaluate(int argc, VALUE *argv, VALUE rb_context)
{
  VALUE search_path, xpath_handler;
  VALUE retval = Qnil;
  xmlXPathContextPtr c_context;
  xmlXPathObjectPtr xpath;
  xmlChar *query;
  VALUE errors = rb_ary_new();

  TypedData_Get_Struct(
    rb_context,
    xmlXPathContext,
    &xml_xpath_context_type,
    c_context
  );

  if (rb_scan_args(argc, argv, "11", &search_path, &xpath_handler) == 1) {
    xpath_handler = Qnil;
  }

  query = (xmlChar *)StringValueCStr(search_path);

  if (Qnil != xpath_handler) {
    /* FIXME: not sure if this is the correct place to shove private data. */
    c_context->userData = (void *)xpath_handler;
    xmlXPathRegisterFuncLookup(
      c_context,
      handler_lookup,
      (void *)xpath_handler
    );
  }

  xmlSetStructuredErrorFunc((void *)errors, noko__error_array_pusher);
  xmlSetGenericErrorFunc((void *)errors, generic_exception_pusher);

  xpath = xmlXPathEvalExpression(query, c_context);

  xmlSetStructuredErrorFunc(NULL, NULL);
  xmlSetGenericErrorFunc(NULL, NULL);

  if (xpath == NULL) {
    rb_exc_raise(rb_ary_entry(errors, 0));
  }

  retval = xpath2ruby(xpath, c_context);
  if (retval == Qundef) {
    retval = noko_xml_node_set_wrap(NULL, DOC_RUBY_OBJECT(c_context->doc));
  }

  xmlXPathFreeNodeSetList(xpath);

  return retval;
}

#register_namespaces(namespaces) ⇒ Object

Register namespaces in namespaces



8
9
10
11
12
13
# File 'lib/nokogiri/xml/xpath_context.rb', line 8

def register_namespaces(namespaces)
  namespaces.each do |k, v|
    k = k.to_s.gsub(/.*:/, "") # strip off 'xmlns:' or 'xml:'
    register_ns(k, v)
  end
end

#register_ns(prefix, uri) ⇒ Object

Register the namespace with prefix and uri for use in future queries.

Returns

self



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'ext/nokogiri/xml_xpath_context.c', line 130

static VALUE
rb_xml_xpath_context_register_ns(VALUE rb_context, VALUE prefix, VALUE uri)
{
  xmlXPathContextPtr c_context;

  TypedData_Get_Struct(
    rb_context,
    xmlXPathContext,
    &xml_xpath_context_type,
    c_context
  );

  xmlXPathRegisterNs(c_context,
                     (const xmlChar *)StringValueCStr(prefix),
                     (const xmlChar *)StringValueCStr(uri)
                    );
  return rb_context;
}

#register_variable(name, value) ⇒ Object

Register the variable name with value for use in future queries.

Returns

self



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'ext/nokogiri/xml_xpath_context.c', line 157

static VALUE
rb_xml_xpath_context_register_variable(VALUE rb_context, VALUE name, VALUE value)
{
  xmlXPathContextPtr c_context;
  xmlXPathObjectPtr xmlValue;

  TypedData_Get_Struct(
    rb_context,
    xmlXPathContext,
    &xml_xpath_context_type,
    c_context
  );

  xmlValue = xmlXPathNewCString(StringValueCStr(value));

  xmlXPathRegisterVariable(
    c_context,
    (const xmlChar *)StringValueCStr(name),
    xmlValue
  );

  return rb_context;
}