Class: Nokogiri::XML::XPathContext

Inherits:
Object
  • Object
show all
Defined in:
lib/nokogiri/xml/xpath_context.rb,
lib/nokogiri/ffi/xml/xpath_context.rb,
ext/nokogiri/xml_xpath_context.c

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#cstructObject

:nodoc:



5
6
7
# File 'lib/nokogiri/ffi/xml/xpath_context.rb', line 5

def cstruct
  @cstruct
end

Class Method Details

.new(node) ⇒ Object

Create a new XPathContext with node as the reference point.



66
67
68
69
70
71
72
73
74
75
# File 'lib/nokogiri/ffi/xml/xpath_context.rb', line 66

def self.new(node) # :nodoc:
  LibXML.xmlXPathInit()

  ptr = LibXML.xmlXPathNewContext(node.cstruct[:doc])

  ctx = allocate
  ctx.cstruct = LibXML::XmlXpathContext.new(ptr)
  ctx.cstruct[:node] = node.cstruct
  ctx
end

Instance Method Details

#evaluate(search_path) ⇒ Object

Evaluate the search_path returning an XML::XPath object.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/nokogiri/ffi/xml/xpath_context.rb', line 11

def evaluate(search_path, xpath_handler=nil) # :nodoc:
  lookup = nil # to keep lambda in scope long enough to avoid a possible GC tragedy
  query = search_path.to_s

  if xpath_handler
    lookup = lambda do |ctx, name, uri|
      return nil unless xpath_handler.respond_to?(name)
      ruby_funcall name, xpath_handler
    end
    LibXML.xmlXPathRegisterFuncLookup(cstruct, lookup, nil);
  end

  exception_handler = lambda do |ctx, error|
    raise XPath::SyntaxError.wrap(error)
  end
  LibXML.xmlResetLastError()
  LibXML.xmlSetStructuredErrorFunc(nil, exception_handler)

  generic_exception_handler = lambda do |ctx, msg|
    raise RuntimeError.new(msg) # TODO: varargs
  end
  LibXML.xmlSetGenericErrorFunc(nil, generic_exception_handler)

  xpath_ptr = LibXML.xmlXPathEvalExpression(query, cstruct)

  LibXML.xmlSetStructuredErrorFunc(nil, nil)
  LibXML.xmlSetGenericErrorFunc(nil, nil)

  if xpath_ptr.null?
    error = LibXML.xmlGetLastError()
    raise XPath::SyntaxError.wrap(error)
  end

  xpath = XML::XPath.new
  xpath.cstruct = LibXML::XmlXpathObject.new(xpath_ptr)
  xpath.document = cstruct.document.ruby_doc

  case xpath.cstruct[:type]
  when LibXML::XmlXpathObject::XPATH_NODESET
    if xpath.cstruct[:nodesetval].null?
      NodeSet.new(xpath.document)
    else
      NodeSet.wrap(xpath.cstruct[:nodesetval], xpath.document)
    end
  when LibXML::XmlXpathObject::XPATH_STRING
    xpath.cstruct[:stringval]
  when LibXML::XmlXpathObject::XPATH_NUMBER
    xpath.cstruct[:floatval]
  when LibXML::XmlXpathObject::XPATH_BOOLEAN
    0 != xpath.cstruct[:boolval]
  else
    NodeSet.new(xpath.document)
  end
end

#register_namespaces(namespaces) ⇒ Object

Register namespaces in namespaces



7
8
9
10
11
12
# File 'lib/nokogiri/xml/xpath_context.rb', line 7

def register_namespaces(namespaces)
  namespaces.each do |k, v|
    k = k.gsub(/.*:/,'') # strip off 'xmlns:' or 'xml:'
    register_ns(k, v)
  end
end

#register_ns(prefix, uri) ⇒ Object

Register the namespace with prefix and uri.



7
8
9
# File 'lib/nokogiri/ffi/xml/xpath_context.rb', line 7

def register_ns(prefix, uri) # :nodoc:
  LibXML.xmlXPathRegisterNs(cstruct, prefix, uri)
end