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