Match node types in node_matches?
The method XPath::Evaluator#node_matches? now has a special case to handle "type-test" nodes. This in turn fixes a bunch of failing tests such as those for the XPath query "parent::node()".
This commit is contained in:
parent
a437d67573
commit
d34e4697de
|
@ -476,12 +476,19 @@ module Oga
|
||||||
# Checks if a given {Oga::XML::Node} instance matches a {Oga::XPath::Node}
|
# Checks if a given {Oga::XML::Node} instance matches a {Oga::XPath::Node}
|
||||||
# instance.
|
# instance.
|
||||||
#
|
#
|
||||||
# Checking if a node matches happens in two steps:
|
# This method can use both "test" and "type-test" nodes. In case of
|
||||||
|
# "type-test" nodes the procedure is as following:
|
||||||
|
#
|
||||||
|
# 1. Evaluate the expression
|
||||||
|
# 2. If the return value is non empty return `true`, otherwise return
|
||||||
|
# `false`
|
||||||
|
#
|
||||||
|
# For "test" nodes the procedure is as following instead:
|
||||||
#
|
#
|
||||||
# 1. Match the name
|
# 1. Match the name
|
||||||
# 2. Match the namespace
|
# 2. Match the namespace
|
||||||
#
|
#
|
||||||
# In both cases a star (`*`) can be used as a wildcard.
|
# For both the name and namespace a wildcard (`*`) can be used.
|
||||||
#
|
#
|
||||||
# @param [Oga::XML::Node] xml_node
|
# @param [Oga::XML::Node] xml_node
|
||||||
# @param [Oga::XPath::Node] ast_node
|
# @param [Oga::XPath::Node] ast_node
|
||||||
|
@ -490,6 +497,10 @@ module Oga
|
||||||
def node_matches?(xml_node, ast_node)
|
def node_matches?(xml_node, ast_node)
|
||||||
ns, name = *ast_node
|
ns, name = *ast_node
|
||||||
|
|
||||||
|
if ast_node.type == :type_test
|
||||||
|
return type_matches?(xml_node, ast_node)
|
||||||
|
end
|
||||||
|
|
||||||
# If only the name is given and is a wildcard then we'll also want to
|
# If only the name is given and is a wildcard then we'll also want to
|
||||||
# match the namespace as a wildcard.
|
# match the namespace as a wildcard.
|
||||||
if !ns and name == '*'
|
if !ns and name == '*'
|
||||||
|
@ -509,6 +520,17 @@ module Oga
|
||||||
return name_matches && ns_matches
|
return name_matches && ns_matches
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# @param [Oga::XML::Node] xml_node
|
||||||
|
# @param [Oga::XPath::Node] ast_node
|
||||||
|
# @return [TrueClass|FalseClass]
|
||||||
|
#
|
||||||
|
def type_matches?(xml_node, ast_node)
|
||||||
|
context = XML::NodeSet.new([xml_node])
|
||||||
|
|
||||||
|
return process(ast_node, context).length > 0
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Returns `true` if the name of the XML node matches the given name *or*
|
# Returns `true` if the name of the XML node matches the given name *or*
|
||||||
# matches a wildcard.
|
# matches a wildcard.
|
||||||
|
|
|
@ -77,6 +77,25 @@ describe Oga::XPath::Evaluator do
|
||||||
example 'return true if a node with a namespace is matched using a wildcard' do
|
example 'return true if a node with a namespace is matched using a wildcard' do
|
||||||
@evaluator.node_matches?(@name_ns_node, s(:test, nil, '*')).should == true
|
@evaluator.node_matches?(@name_ns_node, s(:test, nil, '*')).should == true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
example 'return true if the node type matches' do
|
||||||
|
@evaluator.node_matches?(@name_node, s(:type_test, 'node')).should == true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#type_matches?' do
|
||||||
|
before do
|
||||||
|
@element = Oga::XML::Element.new(:name => 'a')
|
||||||
|
@ns = Oga::XML::Namespace.new(:name => 'a')
|
||||||
|
end
|
||||||
|
|
||||||
|
example 'return true if the type matches' do
|
||||||
|
@evaluator.type_matches?(@element, s(:type_test, 'node')).should == true
|
||||||
|
end
|
||||||
|
|
||||||
|
example 'return false if the type does not match' do
|
||||||
|
@evaluator.type_matches?(@ns, s(:type_test, 'node')).should == false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context '#has_parent?' do
|
context '#has_parent?' do
|
||||||
|
|
Loading…
Reference in New Issue