class Nokogiri::XML::XPathContext - nokogiri-1.15.2 Documentation

# 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, Nokogiri_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;
    }