Nokogiri::XML::XPathContext

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–2016 Aaron Patterson, Mike Dalessio, Charles Nutter, Sergio Arbeo
Patrick Mahoney, Yoko Harada, Akinori Musha, John Shahid
Licensed under the MIT License.

在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号

意见反馈
返回顶部