123456789_123456789_123456789_123456789_123456789_

Class: Nokogiri::XML::XPathContext

Relationships & Source Files
Inherits: Object
Defined in: ext/nokogiri/xml_xpath_context.c,
lib/nokogiri/xml/xpath_context.rb

Overview

XPathContext is the entry point for searching a Document by using XPath.

Class Method Summary

  • .new(node) constructor

    Create a new XPathContext with node as the context node.

Instance Attribute Summary

Instance Method Summary

Constructor Details

.new(node)

Create a new XPathContext with node as the context node.

[ GitHub ]

  
# File 'ext/nokogiri/xml_xpath_context.c', line 422

static VALUE
noko_xml_xpath_context_new(VALUE klass, VALUE rb_node)
{
  xmlNodePtr c_node;
  xmlXPathContextPtr c_context;
  VALUE rb_context;

  Noko_Node_Get_Struct(rb_node, xmlNode, c_node);

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

  c_context = xmlXPathNewContext(c_node->doc);
  c_context->node = c_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,
                         noko_xml_xpath_context_xpath_func_css_class);
  xmlXPathRegisterFuncNS(c_context,
                         (const xmlChar *)"local-name-is", NOKOGIRI_BUILTIN_URI,
                         noko_xml_xpath_context_xpath_func_local_name_is);

  rb_context = TypedData_Wrap_Struct(klass, &_noko_xml_xpath_context_type, c_context);

  return rb_context;
}

Instance Attribute Details

#node=(rb_node) (writeonly)

This method is for internal use only.
[ GitHub ]

  
# File 'ext/nokogiri/xml_xpath_context.c', line 455

static VALUE
noko_xml_xpath_context_set_node(VALUE rb_context, VALUE rb_node)
{
  xmlNodePtr c_node;
  xmlXPathContextPtr c_context;

  TypedData_Get_Struct(rb_context, xmlXPathContext, &_noko_xml_xpath_context_type, c_context);
  Noko_Node_Get_Struct(rb_node, xmlNode, c_node);

  c_context->doc = c_node->doc;
  c_context->node = c_node;

  return rb_node;
}

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.

[ GitHub ]

  
# File 'ext/nokogiri/xml_xpath_context.c', line 364

static VALUE
noko_xml_xpath_context_evaluate(int argc, VALUE *argv, VALUE rb_context)
{
  xmlXPathContextPtr c_context;
  VALUE rb_expression = Qnil;
  VALUE rb_function_lookup_handler = Qnil;
  xmlChar *c_expression_str = NULL;
  VALUE rb_errors = rb_ary_new();
  xmlXPathObjectPtr c_xpath_object;
  VALUE rb_xpath_object = Qnil;

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

  rb_scan_args(argc, argv, "11", &rb_expression, &rb_function_lookup_handler);

  c_expression_str = (xmlChar *)StringValueCStr(rb_expression);

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

  /* TODO: use xmlXPathSetErrorHandler (as of 2.13.0) */
  xmlSetStructuredErrorFunc((void *)rb_errors, noko__error_array_pusher);
  xmlSetGenericErrorFunc((void *)rb_errors, _noko_xml_xpath_context__generic_exception_pusher);

  c_xpath_object = xmlXPathEvalExpression(c_expression_str, c_context);

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

  xmlXPathRegisterFuncLookup(c_context, NULL, NULL);

  if (c_xpath_object == NULL) {
    rb_exc_raise(rb_ary_entry(rb_errors, 0));
  }

  rb_xpath_object = _noko_xml_xpath_context__xpath2ruby(c_xpath_object, c_context);
  if (rb_xpath_object == Qundef) {
    rb_xpath_object = noko_xml_node_set_wrap(NULL, DOC_RUBY_OBJECT(c_context->doc));
  }

  xmlXPathFreeNodeSetList(c_xpath_object);

  return rb_xpath_object;
}

#register_namespaces(namespaces)

Register namespaces in namespaces

[ GitHub ]

  
# File 'lib/nokogiri/xml/xpath_context.rb', line 8

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

    register_ns(key, value)
  end
end

#register_ns(prefix, uri) → Nokogiri::XML::XPathContext)

Register the namespace with prefix and uri for use in future queries. Passing a uri of nil will unregister the namespace.

Returns

self

[ GitHub ]

  
# File 'ext/nokogiri/xml_xpath_context.c', line 131

static VALUE
noko_xml_xpath_context_register_ns(VALUE rb_context, VALUE prefix, VALUE uri)
{
  xmlXPathContextPtr c_context;
  const xmlChar *ns_uri;

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

  if (NIL_P(uri)) {
    ns_uri = NULL;
  } else {
    ns_uri = (const xmlChar *)StringValueCStr(uri);
  }

  xmlXPathRegisterNs(c_context, (const xmlChar *)StringValueCStr(prefix), ns_uri);

  return rb_context;
}

#register_variable(name, value) → Nokogiri::XML::XPathContext)

Register the variable name with value for use in future queries. Passing a value of nil will unregister the variable.

Returns

self

[ GitHub ]

  
# File 'ext/nokogiri/xml_xpath_context.c', line 159

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

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

  if (NIL_P(value)) {
    xmlValue = NULL;
  } else {
    xmlValue = xmlXPathNewCString(StringValueCStr(value));
  }

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

  return rb_context;
}

#register_variables(binds)

[ GitHub ]

  
# File 'lib/nokogiri/xml/xpath_context.rb', line 16

def register_variables(binds)
  return if binds.nil?

  binds.each do |key, value|
    key = key.to_s

    register_variable(key, value)
  end
end