2015-12-16 00:07:31 -05:00
|
|
|
# frozen_string_literal: false
|
2018-11-02 13:52:33 -04:00
|
|
|
require_relative 'functions'
|
|
|
|
require_relative 'xpath_parser'
|
2003-06-09 21:31:01 -04:00
|
|
|
|
|
|
|
module REXML
|
2008-10-01 09:46:53 -04:00
|
|
|
# Wrapper class. Use this class to access the XPath functions.
|
|
|
|
class XPath
|
|
|
|
include Functions
|
2011-05-11 18:56:13 -04:00
|
|
|
# A base Hash object, supposing to be used when initializing a
|
|
|
|
# default empty namespaces set, but is currently unused.
|
|
|
|
# TODO: either set the namespaces=EMPTY_HASH, or deprecate this.
|
2008-10-01 09:46:53 -04:00
|
|
|
EMPTY_HASH = {}
|
2003-06-09 21:31:01 -04:00
|
|
|
|
2008-10-01 09:46:53 -04:00
|
|
|
# Finds and returns the first node that matches the supplied xpath.
|
|
|
|
# element::
|
2011-05-18 17:19:18 -04:00
|
|
|
# The context element
|
2008-10-01 09:46:53 -04:00
|
|
|
# path::
|
2011-05-18 17:19:18 -04:00
|
|
|
# The xpath to search for. If not supplied or nil, returns the first
|
|
|
|
# node matching '*'.
|
2008-10-01 09:46:53 -04:00
|
|
|
# namespaces::
|
2011-05-18 17:19:18 -04:00
|
|
|
# If supplied, a Hash which defines a namespace mapping.
|
2008-12-02 19:31:58 -05:00
|
|
|
# variables::
|
|
|
|
# If supplied, a Hash which maps $variables in the query
|
|
|
|
# to values. This can be used to avoid XPath injection attacks
|
|
|
|
# or to automatically handle escaping string values.
|
2008-10-01 09:46:53 -04:00
|
|
|
#
|
|
|
|
# XPath.first( node )
|
|
|
|
# XPath.first( doc, "//b"} )
|
|
|
|
# XPath.first( node, "a/x:b", { "x"=>"http://doofus" } )
|
2008-12-02 19:31:58 -05:00
|
|
|
# XPath.first( node, '/book/publisher/text()=$publisher', {}, {"publisher"=>"O'Reilly"})
|
2018-04-27 21:36:18 -04:00
|
|
|
def XPath::first(element, path=nil, namespaces=nil, variables={}, options={})
|
2006-09-07 22:03:44 -04:00
|
|
|
raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash)
|
|
|
|
raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash)
|
2018-04-27 21:36:18 -04:00
|
|
|
parser = XPathParser.new(**options)
|
2008-10-01 09:46:53 -04:00
|
|
|
parser.namespaces = namespaces
|
|
|
|
parser.variables = variables
|
|
|
|
path = "*" unless path
|
|
|
|
element = [element] unless element.kind_of? Array
|
|
|
|
parser.parse(path, element).flatten[0]
|
|
|
|
end
|
2003-06-09 21:31:01 -04:00
|
|
|
|
2008-10-01 09:46:53 -04:00
|
|
|
# Iterates over nodes that match the given path, calling the supplied
|
|
|
|
# block with the match.
|
|
|
|
# element::
|
|
|
|
# The context element
|
|
|
|
# path::
|
|
|
|
# The xpath to search for. If not supplied or nil, defaults to '*'
|
|
|
|
# namespaces::
|
2011-05-18 17:19:18 -04:00
|
|
|
# If supplied, a Hash which defines a namespace mapping
|
2008-12-02 19:31:58 -05:00
|
|
|
# variables::
|
|
|
|
# If supplied, a Hash which maps $variables in the query
|
|
|
|
# to values. This can be used to avoid XPath injection attacks
|
|
|
|
# or to automatically handle escaping string values.
|
2008-10-01 09:46:53 -04:00
|
|
|
#
|
|
|
|
# XPath.each( node ) { |el| ... }
|
|
|
|
# XPath.each( node, '/*[@attr='v']' ) { |el| ... }
|
|
|
|
# XPath.each( node, 'ancestor::x' ) { |el| ... }
|
2008-12-02 19:31:58 -05:00
|
|
|
# XPath.each( node, '/book/publisher/text()=$publisher', {}, {"publisher"=>"O'Reilly"}) \
|
|
|
|
# {|el| ... }
|
2018-04-27 21:36:18 -04:00
|
|
|
def XPath::each(element, path=nil, namespaces=nil, variables={}, options={}, &block)
|
2006-09-07 22:03:44 -04:00
|
|
|
raise "The namespaces argument, if supplied, must be a hash object." unless namespaces.nil? or namespaces.kind_of?(Hash)
|
|
|
|
raise "The variables argument, if supplied, must be a hash object." unless variables.kind_of?(Hash)
|
2018-04-27 21:36:18 -04:00
|
|
|
parser = XPathParser.new(**options)
|
2008-10-01 09:46:53 -04:00
|
|
|
parser.namespaces = namespaces
|
|
|
|
parser.variables = variables
|
|
|
|
path = "*" unless path
|
|
|
|
element = [element] unless element.kind_of? Array
|
|
|
|
parser.parse(path, element).each( &block )
|
|
|
|
end
|
2003-06-09 21:31:01 -04:00
|
|
|
|
2009-03-05 22:56:38 -05:00
|
|
|
# Returns an array of nodes matching a given XPath.
|
2018-04-27 21:36:18 -04:00
|
|
|
def XPath::match(element, path=nil, namespaces=nil, variables={}, options={})
|
|
|
|
parser = XPathParser.new(**options)
|
2008-10-01 09:46:53 -04:00
|
|
|
parser.namespaces = namespaces
|
|
|
|
parser.variables = variables
|
|
|
|
path = "*" unless path
|
|
|
|
element = [element] unless element.kind_of? Array
|
|
|
|
parser.parse(path,element)
|
|
|
|
end
|
|
|
|
end
|
2003-06-09 21:31:01 -04:00
|
|
|
end
|