mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
rexml: Fix a XPath bug that white spaces aren't ignored
lib/rexml/parsers/xpathparser.rb: Ignore white spaces in relative location path. test/rexml/xpath/test_base.rb: Add more test patterns and use more debug friendly assertion style. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63204 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
632e10cad3
commit
9090241e61
2 changed files with 58 additions and 44 deletions
|
@ -185,7 +185,7 @@ module REXML
|
|||
# | '/' RelativeLocationPath?
|
||||
# | '//' RelativeLocationPath
|
||||
def LocationPath path, parsed
|
||||
path = path.strip
|
||||
path = path.lstrip
|
||||
if path[0] == ?/
|
||||
parsed << :document
|
||||
if path[1] == ?/
|
||||
|
@ -209,7 +209,12 @@ module REXML
|
|||
# | RelativeLocationPath '//' Step
|
||||
AXIS = /^(ancestor|ancestor-or-self|attribute|child|descendant|descendant-or-self|following|following-sibling|namespace|parent|preceding|preceding-sibling|self)::/
|
||||
def RelativeLocationPath path, parsed
|
||||
while path.size > 0
|
||||
loop do
|
||||
original_path = path
|
||||
path = path.lstrip
|
||||
|
||||
return original_path if path.empty?
|
||||
|
||||
# (axis or @ or <child::>) nodetest predicate >
|
||||
# OR > / Step
|
||||
# (. or ..) >
|
||||
|
@ -239,15 +244,17 @@ module REXML
|
|||
n = []
|
||||
path = NodeTest( path, n)
|
||||
|
||||
if path[0] == ?[
|
||||
path = Predicate( path, n )
|
||||
end
|
||||
|
||||
parsed.concat(n)
|
||||
end
|
||||
|
||||
if path.size > 0
|
||||
if path[0] == ?/
|
||||
original_path = path
|
||||
path = path.lstrip
|
||||
return original_path if path.empty?
|
||||
|
||||
return original_path if path[0] != ?/
|
||||
|
||||
if path[1] == ?/
|
||||
parsed << :descendant_or_self
|
||||
parsed << :node
|
||||
|
@ -255,13 +262,8 @@ module REXML
|
|||
else
|
||||
path = path[1..-1]
|
||||
end
|
||||
else
|
||||
return path
|
||||
end
|
||||
end
|
||||
end
|
||||
return path
|
||||
end
|
||||
|
||||
# Returns a 1-1 map of the nodeset
|
||||
# The contents of the resulting array are either:
|
||||
|
@ -277,6 +279,8 @@ module REXML
|
|||
NODE_TYPE = /^(comment|text|node)\(\s*\)/m
|
||||
PI = /^processing-instruction\(/
|
||||
def NodeTest path, parsed
|
||||
original_path = path
|
||||
path = path.lstrip
|
||||
case path
|
||||
when /^\*/
|
||||
path = $'
|
||||
|
@ -310,13 +314,17 @@ module REXML
|
|||
parsed << :qname
|
||||
parsed << prefix
|
||||
parsed << name
|
||||
else
|
||||
path = original_path
|
||||
end
|
||||
return path
|
||||
end
|
||||
|
||||
# Filters the supplied nodeset on the predicate(s)
|
||||
def Predicate path, parsed
|
||||
return nil unless path[0] == ?[
|
||||
original_path = path
|
||||
path = path.lstrip
|
||||
return original_path unless path[0] == ?[
|
||||
predicates = []
|
||||
while path[0] == ?[
|
||||
path, expr = get_group(path)
|
||||
|
@ -509,8 +517,7 @@ module REXML
|
|||
#| LocationPath
|
||||
#| FilterExpr ('/' | '//') RelativeLocationPath
|
||||
def PathExpr path, parsed
|
||||
path =~ /^\s*/
|
||||
path = $'
|
||||
path = path.lstrip
|
||||
n = []
|
||||
rest = FilterExpr( path, n )
|
||||
if rest != path
|
||||
|
@ -530,7 +537,7 @@ module REXML
|
|||
def FilterExpr path, parsed
|
||||
n = []
|
||||
path = PrimaryExpr( path, n )
|
||||
path = Predicate(path, n) if path and path[0] == ?[
|
||||
path = Predicate(path, n)
|
||||
parsed.concat(n)
|
||||
path
|
||||
end
|
||||
|
|
|
@ -632,29 +632,36 @@ module REXMLTests
|
|||
<c id='a'/>
|
||||
</b>
|
||||
<c id='b'/>
|
||||
<c id='c'/>
|
||||
<c/>
|
||||
</a>")
|
||||
assert_equal( 1, REXML::XPath.match(doc,
|
||||
"//*[local-name()='c' and @id='b']").size )
|
||||
assert_equal( 1, REXML::XPath.match(doc,
|
||||
"//*[ local-name()='c' and @id='b' ]").size )
|
||||
assert_equal( 1, REXML::XPath.match(doc,
|
||||
"//*[ local-name() = 'c' and @id = 'b' ]").size )
|
||||
assert_equal( 1,
|
||||
REXML::XPath.match(doc, '/a/c[@id]').size )
|
||||
assert_equal( 1,
|
||||
REXML::XPath.match(doc, '/a/c[(@id)]').size )
|
||||
assert_equal( 1,
|
||||
REXML::XPath.match(doc, '/a/c[ @id ]').size )
|
||||
assert_equal( 1,
|
||||
REXML::XPath.match(doc, '/a/c[ (@id) ]').size )
|
||||
assert_equal( 1,
|
||||
REXML::XPath.match(doc, '/a/c[( @id )]').size )
|
||||
assert_equal( 1, REXML::XPath.match(doc.root,
|
||||
'/a/c[ ( @id ) ]').size )
|
||||
assert_equal( 1, REXML::XPath.match(doc,
|
||||
'/a/c [ ( @id ) ] ').size )
|
||||
assert_equal( 1, REXML::XPath.match(doc,
|
||||
' / a / c [ ( @id ) ] ').size )
|
||||
match = lambda do |xpath|
|
||||
REXML::XPath.match(doc, xpath).collect(&:to_s)
|
||||
end
|
||||
assert_equal(["<c id='b'/>"],
|
||||
match.call("//*[local-name()='c' and @id='b']"))
|
||||
assert_equal(["<c id='b'/>"],
|
||||
match.call("//*[ local-name()='c' and @id='b' ]"))
|
||||
assert_equal(["<c id='b'/>"],
|
||||
match.call("//*[ local-name() = 'c' and @id = 'b' ]"))
|
||||
assert_equal(["<c id='b'/>", "<c id='c'/>"],
|
||||
match.call('/a/c[@id]'))
|
||||
assert_equal(["<c id='b'/>", "<c id='c'/>"],
|
||||
match.call('/a/c[(@id)]'))
|
||||
assert_equal(["<c id='b'/>", "<c id='c'/>"],
|
||||
match.call('/a/c[ @id ]'))
|
||||
assert_equal(["<c id='b'/>", "<c id='c'/>"],
|
||||
match.call('/a/c[ (@id) ]'))
|
||||
assert_equal(["<c id='b'/>", "<c id='c'/>"],
|
||||
match.call('/a/c[( @id )]'))
|
||||
assert_equal(["<c id='b'/>", "<c id='c'/>"],
|
||||
match.call('/a/c[ ( @id ) ]'))
|
||||
assert_equal(["<c id='b'/>", "<c id='c'/>"],
|
||||
match.call('/a/c [ ( @id ) ] '))
|
||||
assert_equal(["<c id='b'/>", "<c id='c'/>"],
|
||||
match.call(' / a / c [ ( @id ) ] '))
|
||||
assert_equal(["<c id='b'/>", "<c id='c'/>"],
|
||||
match.call('/ a / child:: c [( @id )] /'))
|
||||
end
|
||||
|
||||
def test_text_nodes
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue