mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/xmlrpc, lib/rexml, test/ruby/test_array.rb,
test/ruby/test_unicode_escape.rb, test/scanf/test_scanf.rb, test/rss/rss-assertions.rb: fix indentation to remove warning. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19657 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
952385b712
commit
46321a9a31
40 changed files with 2198 additions and 2192 deletions
|
@ -2,262 +2,262 @@ require 'rexml/functions'
|
|||
require 'rexml/xmltokens'
|
||||
|
||||
module REXML
|
||||
class QuickPath
|
||||
include Functions
|
||||
include XMLTokens
|
||||
class QuickPath
|
||||
include Functions
|
||||
include XMLTokens
|
||||
|
||||
EMPTY_HASH = {}
|
||||
EMPTY_HASH = {}
|
||||
|
||||
def QuickPath::first element, path, namespaces=EMPTY_HASH
|
||||
match(element, path, namespaces)[0]
|
||||
end
|
||||
def QuickPath::first element, path, namespaces=EMPTY_HASH
|
||||
match(element, path, namespaces)[0]
|
||||
end
|
||||
|
||||
def QuickPath::each element, path, namespaces=EMPTY_HASH, &block
|
||||
path = "*" unless path
|
||||
match(element, path, namespaces).each( &block )
|
||||
end
|
||||
def QuickPath::each element, path, namespaces=EMPTY_HASH, &block
|
||||
path = "*" unless path
|
||||
match(element, path, namespaces).each( &block )
|
||||
end
|
||||
|
||||
def QuickPath::match element, path, namespaces=EMPTY_HASH
|
||||
raise "nil is not a valid xpath" unless path
|
||||
results = nil
|
||||
Functions::namespace_context = namespaces
|
||||
case path
|
||||
when /^\/([^\/]|$)/u
|
||||
# match on root
|
||||
path = path[1..-1]
|
||||
return [element.root.parent] if path == ''
|
||||
results = filter([element.root], path)
|
||||
when /^[-\w]*::/u
|
||||
results = filter([element], path)
|
||||
when /^\*/u
|
||||
results = filter(element.to_a, path)
|
||||
when /^[\[!\w:]/u
|
||||
# match on child
|
||||
matches = []
|
||||
children = element.to_a
|
||||
results = filter(children, path)
|
||||
else
|
||||
results = filter([element], path)
|
||||
end
|
||||
return results
|
||||
end
|
||||
def QuickPath::match element, path, namespaces=EMPTY_HASH
|
||||
raise "nil is not a valid xpath" unless path
|
||||
results = nil
|
||||
Functions::namespace_context = namespaces
|
||||
case path
|
||||
when /^\/([^\/]|$)/u
|
||||
# match on root
|
||||
path = path[1..-1]
|
||||
return [element.root.parent] if path == ''
|
||||
results = filter([element.root], path)
|
||||
when /^[-\w]*::/u
|
||||
results = filter([element], path)
|
||||
when /^\*/u
|
||||
results = filter(element.to_a, path)
|
||||
when /^[\[!\w:]/u
|
||||
# match on child
|
||||
matches = []
|
||||
children = element.to_a
|
||||
results = filter(children, path)
|
||||
else
|
||||
results = filter([element], path)
|
||||
end
|
||||
return results
|
||||
end
|
||||
|
||||
# Given an array of nodes it filters the array based on the path. The
|
||||
# result is that when this method returns, the array will contain elements
|
||||
# which match the path
|
||||
def QuickPath::filter elements, path
|
||||
return elements if path.nil? or path == '' or elements.size == 0
|
||||
case path
|
||||
when /^\/\//u # Descendant
|
||||
return axe( elements, "descendant-or-self", $' )
|
||||
when /^\/?\b(\w[-\w]*)\b::/u # Axe
|
||||
axe_name = $1
|
||||
rest = $'
|
||||
return axe( elements, $1, $' )
|
||||
when /^\/(?=\b([:!\w][-\.\w]*:)?[-!\*\.\w]*\b([^:(]|$)|\*)/u # Child
|
||||
rest = $'
|
||||
results = []
|
||||
elements.each do |element|
|
||||
results |= filter( element.to_a, rest )
|
||||
end
|
||||
return results
|
||||
when /^\/?(\w[-\w]*)\(/u # / Function
|
||||
return function( elements, $1, $' )
|
||||
when Namespace::NAMESPLIT # Element name
|
||||
name = $2
|
||||
ns = $1
|
||||
rest = $'
|
||||
elements.delete_if do |element|
|
||||
!(element.kind_of? Element and
|
||||
(element.expanded_name == name or
|
||||
(element.name == name and
|
||||
element.namespace == Functions.namespace_context[ns])))
|
||||
end
|
||||
return filter( elements, rest )
|
||||
when /^\/\[/u
|
||||
matches = []
|
||||
elements.each do |element|
|
||||
matches |= predicate( element.to_a, path[1..-1] ) if element.kind_of? Element
|
||||
end
|
||||
return matches
|
||||
when /^\[/u # Predicate
|
||||
return predicate( elements, path )
|
||||
when /^\/?\.\.\./u # Ancestor
|
||||
return axe( elements, "ancestor", $' )
|
||||
when /^\/?\.\./u # Parent
|
||||
return filter( elements.collect{|e|e.parent}, $' )
|
||||
when /^\/?\./u # Self
|
||||
return filter( elements, $' )
|
||||
when /^\*/u # Any
|
||||
results = []
|
||||
elements.each do |element|
|
||||
results |= filter( [element], $' ) if element.kind_of? Element
|
||||
#if element.kind_of? Element
|
||||
# children = element.to_a
|
||||
# children.delete_if { |child| !child.kind_of?(Element) }
|
||||
# results |= filter( children, $' )
|
||||
#end
|
||||
end
|
||||
return results
|
||||
end
|
||||
return []
|
||||
end
|
||||
# Given an array of nodes it filters the array based on the path. The
|
||||
# result is that when this method returns, the array will contain elements
|
||||
# which match the path
|
||||
def QuickPath::filter elements, path
|
||||
return elements if path.nil? or path == '' or elements.size == 0
|
||||
case path
|
||||
when /^\/\//u # Descendant
|
||||
return axe( elements, "descendant-or-self", $' )
|
||||
when /^\/?\b(\w[-\w]*)\b::/u # Axe
|
||||
axe_name = $1
|
||||
rest = $'
|
||||
return axe( elements, $1, $' )
|
||||
when /^\/(?=\b([:!\w][-\.\w]*:)?[-!\*\.\w]*\b([^:(]|$)|\*)/u # Child
|
||||
rest = $'
|
||||
results = []
|
||||
elements.each do |element|
|
||||
results |= filter( element.to_a, rest )
|
||||
end
|
||||
return results
|
||||
when /^\/?(\w[-\w]*)\(/u # / Function
|
||||
return function( elements, $1, $' )
|
||||
when Namespace::NAMESPLIT # Element name
|
||||
name = $2
|
||||
ns = $1
|
||||
rest = $'
|
||||
elements.delete_if do |element|
|
||||
!(element.kind_of? Element and
|
||||
(element.expanded_name == name or
|
||||
(element.name == name and
|
||||
element.namespace == Functions.namespace_context[ns])))
|
||||
end
|
||||
return filter( elements, rest )
|
||||
when /^\/\[/u
|
||||
matches = []
|
||||
elements.each do |element|
|
||||
matches |= predicate( element.to_a, path[1..-1] ) if element.kind_of? Element
|
||||
end
|
||||
return matches
|
||||
when /^\[/u # Predicate
|
||||
return predicate( elements, path )
|
||||
when /^\/?\.\.\./u # Ancestor
|
||||
return axe( elements, "ancestor", $' )
|
||||
when /^\/?\.\./u # Parent
|
||||
return filter( elements.collect{|e|e.parent}, $' )
|
||||
when /^\/?\./u # Self
|
||||
return filter( elements, $' )
|
||||
when /^\*/u # Any
|
||||
results = []
|
||||
elements.each do |element|
|
||||
results |= filter( [element], $' ) if element.kind_of? Element
|
||||
#if element.kind_of? Element
|
||||
# children = element.to_a
|
||||
# children.delete_if { |child| !child.kind_of?(Element) }
|
||||
# results |= filter( children, $' )
|
||||
#end
|
||||
end
|
||||
return results
|
||||
end
|
||||
return []
|
||||
end
|
||||
|
||||
def QuickPath::axe( elements, axe_name, rest )
|
||||
matches = []
|
||||
matches = filter( elements.dup, rest ) if axe_name =~ /-or-self$/u
|
||||
case axe_name
|
||||
when /^descendant/u
|
||||
elements.each do |element|
|
||||
matches |= filter( element.to_a, "descendant-or-self::#{rest}" ) if element.kind_of? Element
|
||||
end
|
||||
when /^ancestor/u
|
||||
elements.each do |element|
|
||||
while element.parent
|
||||
matches << element.parent
|
||||
element = element.parent
|
||||
end
|
||||
end
|
||||
matches = filter( matches, rest )
|
||||
when "self"
|
||||
matches = filter( elements, rest )
|
||||
when "child"
|
||||
elements.each do |element|
|
||||
matches |= filter( element.to_a, rest ) if element.kind_of? Element
|
||||
end
|
||||
when "attribute"
|
||||
elements.each do |element|
|
||||
matches << element.attributes[ rest ] if element.kind_of? Element
|
||||
end
|
||||
when "parent"
|
||||
matches = filter(elements.collect{|element| element.parent}.uniq, rest)
|
||||
when "following-sibling"
|
||||
matches = filter(elements.collect{|element| element.next_sibling}.uniq,
|
||||
rest)
|
||||
when "previous-sibling"
|
||||
matches = filter(elements.collect{|element|
|
||||
element.previous_sibling}.uniq, rest )
|
||||
end
|
||||
return matches.uniq
|
||||
end
|
||||
def QuickPath::axe( elements, axe_name, rest )
|
||||
matches = []
|
||||
matches = filter( elements.dup, rest ) if axe_name =~ /-or-self$/u
|
||||
case axe_name
|
||||
when /^descendant/u
|
||||
elements.each do |element|
|
||||
matches |= filter( element.to_a, "descendant-or-self::#{rest}" ) if element.kind_of? Element
|
||||
end
|
||||
when /^ancestor/u
|
||||
elements.each do |element|
|
||||
while element.parent
|
||||
matches << element.parent
|
||||
element = element.parent
|
||||
end
|
||||
end
|
||||
matches = filter( matches, rest )
|
||||
when "self"
|
||||
matches = filter( elements, rest )
|
||||
when "child"
|
||||
elements.each do |element|
|
||||
matches |= filter( element.to_a, rest ) if element.kind_of? Element
|
||||
end
|
||||
when "attribute"
|
||||
elements.each do |element|
|
||||
matches << element.attributes[ rest ] if element.kind_of? Element
|
||||
end
|
||||
when "parent"
|
||||
matches = filter(elements.collect{|element| element.parent}.uniq, rest)
|
||||
when "following-sibling"
|
||||
matches = filter(elements.collect{|element| element.next_sibling}.uniq,
|
||||
rest)
|
||||
when "previous-sibling"
|
||||
matches = filter(elements.collect{|element|
|
||||
element.previous_sibling}.uniq, rest )
|
||||
end
|
||||
return matches.uniq
|
||||
end
|
||||
|
||||
# A predicate filters a node-set with respect to an axis to produce a
|
||||
# new node-set. For each node in the node-set to be filtered, the
|
||||
# PredicateExpr is evaluated with that node as the context node, with
|
||||
# the number of nodes in the node-set as the context size, and with the
|
||||
# proximity position of the node in the node-set with respect to the
|
||||
# axis as the context position; if PredicateExpr evaluates to true for
|
||||
# that node, the node is included in the new node-set; otherwise, it is
|
||||
# not included.
|
||||
#
|
||||
# A PredicateExpr is evaluated by evaluating the Expr and converting
|
||||
# the result to a boolean. If the result is a number, the result will
|
||||
# be converted to true if the number is equal to the context position
|
||||
# and will be converted to false otherwise; if the result is not a
|
||||
# number, then the result will be converted as if by a call to the
|
||||
# boolean function. Thus a location path para[3] is equivalent to
|
||||
# para[position()=3].
|
||||
def QuickPath::predicate( elements, path )
|
||||
ind = 1
|
||||
bcount = 1
|
||||
while bcount > 0
|
||||
bcount += 1 if path[ind] == ?[
|
||||
bcount -= 1 if path[ind] == ?]
|
||||
ind += 1
|
||||
end
|
||||
ind -= 1
|
||||
predicate = path[1..ind-1]
|
||||
rest = path[ind+1..-1]
|
||||
# A predicate filters a node-set with respect to an axis to produce a
|
||||
# new node-set. For each node in the node-set to be filtered, the
|
||||
# PredicateExpr is evaluated with that node as the context node, with
|
||||
# the number of nodes in the node-set as the context size, and with the
|
||||
# proximity position of the node in the node-set with respect to the
|
||||
# axis as the context position; if PredicateExpr evaluates to true for
|
||||
# that node, the node is included in the new node-set; otherwise, it is
|
||||
# not included.
|
||||
#
|
||||
# A PredicateExpr is evaluated by evaluating the Expr and converting
|
||||
# the result to a boolean. If the result is a number, the result will
|
||||
# be converted to true if the number is equal to the context position
|
||||
# and will be converted to false otherwise; if the result is not a
|
||||
# number, then the result will be converted as if by a call to the
|
||||
# boolean function. Thus a location path para[3] is equivalent to
|
||||
# para[position()=3].
|
||||
def QuickPath::predicate( elements, path )
|
||||
ind = 1
|
||||
bcount = 1
|
||||
while bcount > 0
|
||||
bcount += 1 if path[ind] == ?[
|
||||
bcount -= 1 if path[ind] == ?]
|
||||
ind += 1
|
||||
end
|
||||
ind -= 1
|
||||
predicate = path[1..ind-1]
|
||||
rest = path[ind+1..-1]
|
||||
|
||||
# have to change 'a [=<>] b [=<>] c' into 'a [=<>] b and b [=<>] c'
|
||||
predicate.gsub!( /([^\s(and)(or)<>=]+)\s*([<>=])\s*([^\s(and)(or)<>=]+)\s*([<>=])\s*([^\s(and)(or)<>=]+)/u,
|
||||
'\1 \2 \3 and \3 \4 \5' )
|
||||
# Let's do some Ruby trickery to avoid some work:
|
||||
predicate.gsub!( /&/u, "&&" )
|
||||
predicate.gsub!( /=/u, "==" )
|
||||
predicate.gsub!( /@(\w[-\w.]*)/u, 'attribute("\1")' )
|
||||
predicate.gsub!( /\bmod\b/u, "%" )
|
||||
predicate.gsub!( /\b(\w[-\w.]*\()/u ) {
|
||||
fname = $1
|
||||
fname.gsub( /-/u, "_" )
|
||||
}
|
||||
|
||||
Functions.pair = [ 0, elements.size ]
|
||||
results = []
|
||||
elements.each do |element|
|
||||
Functions.pair[0] += 1
|
||||
Functions.node = element
|
||||
res = eval( predicate )
|
||||
case res
|
||||
when true
|
||||
results << element
|
||||
when Fixnum
|
||||
results << element if Functions.pair[0] == res
|
||||
when String
|
||||
results << element
|
||||
end
|
||||
end
|
||||
return filter( results, rest )
|
||||
end
|
||||
# have to change 'a [=<>] b [=<>] c' into 'a [=<>] b and b [=<>] c'
|
||||
predicate.gsub!( /([^\s(and)(or)<>=]+)\s*([<>=])\s*([^\s(and)(or)<>=]+)\s*([<>=])\s*([^\s(and)(or)<>=]+)/u,
|
||||
'\1 \2 \3 and \3 \4 \5' )
|
||||
# Let's do some Ruby trickery to avoid some work:
|
||||
predicate.gsub!( /&/u, "&&" )
|
||||
predicate.gsub!( /=/u, "==" )
|
||||
predicate.gsub!( /@(\w[-\w.]*)/u, 'attribute("\1")' )
|
||||
predicate.gsub!( /\bmod\b/u, "%" )
|
||||
predicate.gsub!( /\b(\w[-\w.]*\()/u ) {
|
||||
fname = $1
|
||||
fname.gsub( /-/u, "_" )
|
||||
}
|
||||
|
||||
Functions.pair = [ 0, elements.size ]
|
||||
results = []
|
||||
elements.each do |element|
|
||||
Functions.pair[0] += 1
|
||||
Functions.node = element
|
||||
res = eval( predicate )
|
||||
case res
|
||||
when true
|
||||
results << element
|
||||
when Fixnum
|
||||
results << element if Functions.pair[0] == res
|
||||
when String
|
||||
results << element
|
||||
end
|
||||
end
|
||||
return filter( results, rest )
|
||||
end
|
||||
|
||||
def QuickPath::attribute( name )
|
||||
return Functions.node.attributes[name] if Functions.node.kind_of? Element
|
||||
end
|
||||
def QuickPath::attribute( name )
|
||||
return Functions.node.attributes[name] if Functions.node.kind_of? Element
|
||||
end
|
||||
|
||||
def QuickPath::name()
|
||||
return Functions.node.name if Functions.node.kind_of? Element
|
||||
end
|
||||
def QuickPath::name()
|
||||
return Functions.node.name if Functions.node.kind_of? Element
|
||||
end
|
||||
|
||||
def QuickPath::method_missing( id, *args )
|
||||
begin
|
||||
Functions.send( id.id2name, *args )
|
||||
rescue Exception
|
||||
raise "METHOD: #{id.id2name}(#{args.join ', '})\n#{$!.message}"
|
||||
end
|
||||
end
|
||||
def QuickPath::method_missing( id, *args )
|
||||
begin
|
||||
Functions.send( id.id2name, *args )
|
||||
rescue Exception
|
||||
raise "METHOD: #{id.id2name}(#{args.join ', '})\n#{$!.message}"
|
||||
end
|
||||
end
|
||||
|
||||
def QuickPath::function( elements, fname, rest )
|
||||
args = parse_args( elements, rest )
|
||||
Functions.pair = [0, elements.size]
|
||||
results = []
|
||||
elements.each do |element|
|
||||
Functions.pair[0] += 1
|
||||
Functions.node = element
|
||||
res = Functions.send( fname, *args )
|
||||
case res
|
||||
when true
|
||||
results << element
|
||||
when Fixnum
|
||||
results << element if Functions.pair[0] == res
|
||||
end
|
||||
end
|
||||
return results
|
||||
end
|
||||
def QuickPath::function( elements, fname, rest )
|
||||
args = parse_args( elements, rest )
|
||||
Functions.pair = [0, elements.size]
|
||||
results = []
|
||||
elements.each do |element|
|
||||
Functions.pair[0] += 1
|
||||
Functions.node = element
|
||||
res = Functions.send( fname, *args )
|
||||
case res
|
||||
when true
|
||||
results << element
|
||||
when Fixnum
|
||||
results << element if Functions.pair[0] == res
|
||||
end
|
||||
end
|
||||
return results
|
||||
end
|
||||
|
||||
def QuickPath::parse_args( element, string )
|
||||
# /.*?(?:\)|,)/
|
||||
arguments = []
|
||||
buffer = ""
|
||||
while string and string != ""
|
||||
c = string[0]
|
||||
string.sub!(/^./u, "")
|
||||
case c
|
||||
when ?,
|
||||
# if depth = 1, then we start a new argument
|
||||
arguments << evaluate( buffer )
|
||||
#arguments << evaluate( string[0..count] )
|
||||
when ?(
|
||||
# start a new method call
|
||||
function( element, buffer, string )
|
||||
buffer = ""
|
||||
when ?)
|
||||
# close the method call and return arguments
|
||||
return arguments
|
||||
else
|
||||
buffer << c
|
||||
end
|
||||
end
|
||||
""
|
||||
end
|
||||
end
|
||||
def QuickPath::parse_args( element, string )
|
||||
# /.*?(?:\)|,)/
|
||||
arguments = []
|
||||
buffer = ""
|
||||
while string and string != ""
|
||||
c = string[0]
|
||||
string.sub!(/^./u, "")
|
||||
case c
|
||||
when ?,
|
||||
# if depth = 1, then we start a new argument
|
||||
arguments << evaluate( buffer )
|
||||
#arguments << evaluate( string[0..count] )
|
||||
when ?(
|
||||
# start a new method call
|
||||
function( element, buffer, string )
|
||||
buffer = ""
|
||||
when ?)
|
||||
# close the method call and return arguments
|
||||
return arguments
|
||||
else
|
||||
buffer << c
|
||||
end
|
||||
end
|
||||
""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue