class Nokogiri::XML::XPathContext

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

Public Class Methods

new(node) click to toggle source

Create a new XPathContext with node as the context node.

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;
}

Public Instance Methods

evaluate(search_path, handler = nil) → Object click to toggle source

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.

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) click to toggle source

Register namespaces in namespaces

# 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) → Nokogiri::XML::XPathContext click to toggle source

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

Returns

self

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) → Nokogiri::XML::XPathContext click to toggle source

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

Returns

self

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;
}