Basic support for the XPath last() function.

This commit is contained in:
Yorick Peterse 2014-08-18 19:00:32 +02:00
parent 2817784e6b
commit 423af37422
2 changed files with 58 additions and 1 deletions

View File

@ -98,12 +98,16 @@ module Oga
# @return [Oga::XML::NodeSet]
#
def on_test(ast_node, context)
nodes = XML::NodeSet.new
nodes = XML::NodeSet.new
predicate = ast_node.children[2]
context.each do |xml_node|
nodes << xml_node if node_matches?(xml_node, ast_node)
end
# Filter the nodes based on the predicate.
nodes = process(predicate, nodes) if predicate
return nodes
end
@ -523,6 +527,42 @@ module Oga
return process(left, context) + process(right, context)
end
##
# Delegates function calls to specific handlers.
#
# Handler functions take two arguments:
#
# 1. The context node set
# 2. A variable list of XPath function arguments, passed as individual
# Ruby method arguments.
#
# @param [Oga::XPath::Node] ast_node
# @param [Oga::XML::NodeSet] context
# @return [Oga::XML::NodeSet]
#
def on_call(ast_node, context)
name, args = *ast_node
handler = name.gsub('-', '_')
return send("on_call_#{handler}", context, *args)
end
##
# Processes the `last()` function call. This function call returns a node
# set containing the last node of the context set.
#
# @param [Oga::XML::NodeSet] context
# @return [Oga::XML::NodeSet]
#
def on_call_last(context)
if context.empty?
return context
else
return XML::NodeSet.new([context.last])
end
end
##
# Returns a node set containing all the child nodes of the given set of
# nodes.

View File

@ -0,0 +1,17 @@
require 'spec_helper'
describe Oga::XPath::Evaluator do
context 'last() function' do
before do
@document = parse('<root><a>foo</a><a>bar</a></root>')
@second_a = @document.children[0].children[1]
@set = described_class.new(@document).evaluate('root/a[last()]')
end
it_behaves_like :node_set, :length => 1
example 'return the second <a> node' do
@set[0].should == @second_a
end
end
end