Support for binding/evaluating XPath variables.
This commit is contained in:
parent
5a0e8c5480
commit
ad34ab47a0
|
@ -45,13 +45,29 @@ module Oga
|
||||||
# For more information on the specification, see
|
# For more information on the specification, see
|
||||||
# <http://www.w3.org/TR/xpath/#numbers>.
|
# <http://www.w3.org/TR/xpath/#numbers>.
|
||||||
#
|
#
|
||||||
|
# ## Variables
|
||||||
|
#
|
||||||
|
# The evaluator supports the binding of custom variables in the
|
||||||
|
# {#initialize} method. Variables can be bound by passing in a Hash with the
|
||||||
|
# keys set to the variable names (minus the `$` sign) and their values to
|
||||||
|
# the variable values. The keys of the variables Hash *must* be Strings.
|
||||||
|
#
|
||||||
|
# A basic example:
|
||||||
|
#
|
||||||
|
# evaluator = Evaluator.new(document, 'number' => 10)
|
||||||
|
#
|
||||||
|
# evaluator.evaluate('$number') # => 10
|
||||||
|
#
|
||||||
class Evaluator
|
class Evaluator
|
||||||
##
|
##
|
||||||
# @param [Oga::XML::Document|Oga::XML::Node] document
|
# @param [Oga::XML::Document|Oga::XML::Node] document
|
||||||
|
# @param [Hash] variables Hash containing variables to expose to the XPath
|
||||||
|
# expressions.
|
||||||
#
|
#
|
||||||
def initialize(document)
|
def initialize(document, variables = {})
|
||||||
@document = document
|
@document = document
|
||||||
@nodes = []
|
@nodes = []
|
||||||
|
@variables = variables
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -1490,6 +1506,25 @@ module Oga
|
||||||
return ast_node.children[0]
|
return ast_node.children[0]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Processes a variable reference. If the variable is not defined an error
|
||||||
|
# is raised.
|
||||||
|
#
|
||||||
|
# @param [Oga::XPath::Node] ast_node
|
||||||
|
# @param [Oga::XML::NodeSet] context
|
||||||
|
# @return [Mixed]
|
||||||
|
# @raise [RuntimeError]
|
||||||
|
#
|
||||||
|
def on_var(ast_node, context)
|
||||||
|
name = ast_node.children[0]
|
||||||
|
|
||||||
|
if @variables.key?(name)
|
||||||
|
return @variables[name]
|
||||||
|
else
|
||||||
|
raise "Undefined XPath variable: #{name}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Returns the node for a function call. This node is either the first node
|
# Returns the node for a function call. This node is either the first node
|
||||||
# in the supplied node set, or the first node in the current context.
|
# in the supplied node set, or the first node in the current context.
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Oga::XPath::Evaluator do
|
||||||
|
context 'variable bindings' do
|
||||||
|
before do
|
||||||
|
@document = parse('<a></a>')
|
||||||
|
end
|
||||||
|
|
||||||
|
example 'evaluate a variable' do
|
||||||
|
evaluator = described_class.new(@document, 'number' => 10.0)
|
||||||
|
|
||||||
|
evaluator.evaluate('$number').should == 10.0
|
||||||
|
end
|
||||||
|
|
||||||
|
example 'raise RuntimeError when evaluating an unbound variable' do
|
||||||
|
evaluator = described_class.new(@document)
|
||||||
|
block = lambda { evaluator.evaluate('$number') }
|
||||||
|
|
||||||
|
block.should raise_error 'Undefined XPath variable: number'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue