Evaluation of XPath "ancestor" axes.

This commit is contained in:
Yorick Peterse 2014-07-14 09:42:52 +02:00
parent 30bbd2378e
commit 0211f60826
1 changed files with 52 additions and 19 deletions

View File

@ -13,8 +13,13 @@ module Oga
end
def evaluate(string)
ast = Parser.new(string).parse
context = @document.children
ast = Parser.new(string).parse
if @document.is_a?(XML::Document)
context = @document.children
else
context = XML::NodeSet.new([@document])
end
return process(ast, context)
end
@ -51,25 +56,12 @@ module Oga
end
def on_test(node, context)
ns, name = *node
nodes = XML::NodeSet.new
nodes = XML::NodeSet.new
context.each do |xml_node|
next unless xml_node.is_a?(XML::Element)
name_matches = xml_node.name == name || name == '*'
ns_matches = false
if ns
ns_matches = xml_node.namespace == ns || ns == '*'
# If there's no namespace given but the name matches we'll also mark
# the namespace as matching.
elsif name_matches
ns_matches = true
end
if name_matches and ns_matches
# TODO: change this when attribute tests are implemented since those
# are not XML::Element instances.
if xml_node.is_a?(XML::Element) and node_matches?(xml_node, node)
nodes << xml_node
end
end
@ -77,6 +69,29 @@ module Oga
return nodes
end
def on_axis(node, context)
name, test = *node
return send("on_axis_#{name}", test, context)
end
def on_axis_ancestor(node, context)
nodes = XML::NodeSet.new
context.each do |xml_node|
while xml_node.respond_to?(:parent) and xml_node.parent
xml_node = xml_node.parent
if node_matches?(xml_node, node)
nodes << xml_node
break
end
end
end
return nodes
end
def child_nodes(nodes)
children = XML::NodeSet.new
@ -88,6 +103,24 @@ module Oga
return children
end
def node_matches?(xml_node, ast_node)
ns, name = *ast_node
name_matches = xml_node.name == name || name == '*'
ns_matches = false
if ns
ns_matches = xml_node.namespace == ns || ns == '*'
# If there's no namespace given but the name matches we'll also mark
# the namespace as matching.
elsif name_matches
ns_matches = true
end
return name_matches && ns_matches
end
end # Evaluator
end # XPath
end # Oga