W3cubDocs

/Nokogiri

class Nokogiri::XML::XPathContext

Parent:
Object

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

Public Class Methods

new(node) Show source

Create a new XPathContext with node as the reference point.

static VALUE new(VALUE klass, VALUE nodeobj)
{
  xmlNodePtr node;
  xmlXPathContextPtr ctx;
  VALUE self;

  xmlXPathInit();

  Data_Get_Struct(nodeobj, xmlNode, node);

  ctx = xmlXPathNewContext(node->doc);
  ctx->node = node;
  self = Data_Wrap_Struct(klass, 0, deallocate, ctx);
  /*rb_iv_set(self, "@xpath_handler", Qnil); */
  return self;
}

Public Instance Methods

evaluate(search_path, handler = nil) Show source

Evaluate the search_path returning an XML::XPath object.

static VALUE evaluate(int argc, VALUE *argv, VALUE self)
{
  VALUE search_path, xpath_handler;
  VALUE thing = Qnil;
  xmlXPathContextPtr ctx;
  xmlXPathObjectPtr xpath;
  xmlChar *query;

  Data_Get_Struct(self, xmlXPathContext, ctx);

  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. */
    ctx->userData = (void *)xpath_handler;
    xmlXPathRegisterFuncLookup(ctx, lookup, (void *)xpath_handler);
  }

  xmlResetLastError();
  xmlSetStructuredErrorFunc(NULL, Nokogiri_error_raise);

  /* For some reason, xmlXPathEvalExpression will blow up with a generic error */
  /* when there is a non existent function. */
  xmlSetGenericErrorFunc(NULL, xpath_generic_exception_handler);

  xpath = xmlXPathEvalExpression(query, ctx);
  xmlSetStructuredErrorFunc(NULL, NULL);
  xmlSetGenericErrorFunc(NULL, NULL);

  if(xpath == NULL) {
    xmlErrorPtr error = xmlGetLastError();
    rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
  }

  assert(ctx->doc);
  assert(DOC_RUBY_OBJECT_TEST(ctx->doc));

  switch(xpath->type) {
    case XPATH_STRING:
      thing = NOKOGIRI_STR_NEW2(xpath->stringval);
      xmlFree(xpath->stringval);
      break;
    case XPATH_NODESET:
      thing = Nokogiri_wrap_xml_node_set(xpath->nodesetval,
                                         DOC_RUBY_OBJECT(ctx->doc));
      break;
    case XPATH_NUMBER:
      thing = rb_float_new(xpath->floatval);
      break;
    case XPATH_BOOLEAN:
      thing = xpath->boolval == 1 ? Qtrue : Qfalse;
      break;
    default:
      thing = Nokogiri_wrap_xml_node_set(NULL, DOC_RUBY_OBJECT(ctx->doc));
  }

  xmlXPathFreeNodeSetList(xpath);

  return thing;
}
register_namespaces(namespaces) Show source

Register namespaces in namespaces

# File lib/nokogiri/xml/xpath_context.rb, line 7
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) Show source

Register the namespace with prefix and uri.

static VALUE register_ns(VALUE self, VALUE prefix, VALUE uri)
{
  xmlXPathContextPtr ctx;
  Data_Get_Struct(self, xmlXPathContext, ctx);

  xmlXPathRegisterNs( ctx,
                      (const xmlChar *)StringValueCStr(prefix),
                      (const xmlChar *)StringValueCStr(uri)
  );
  return self;
}
register_variable(name, value) Show source

Register the variable name with value.

static VALUE register_variable(VALUE self, VALUE name, VALUE value)
{
   xmlXPathContextPtr ctx;
   xmlXPathObjectPtr xmlValue;
   Data_Get_Struct(self, xmlXPathContext, ctx);

   xmlValue = xmlXPathNewCString(StringValueCStr(value));

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

   return self;
}

© 2008–2017 Aaron Patterson, Mike Dalessio, Charles Nutter, Sergio Arbeo
Patrick Mahoney, Yoko Harada, Akinori Musha, John Shahid
Licensed under the MIT License.