From e0895be6750d15b6635c49153a957ec4eb14fe97 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Tue, 19 Aug 2014 19:56:56 +0200 Subject: [PATCH] Better setup for XPath predicates. This allows filtering of nodes by indexes (e.g. using last() or a literal number) and uses the correct index range (1 to N in XPath). The function position() is not yet supported as this requires access to the current node, which isn't passed down the call stack just yet. --- lib/oga/xpath/evaluator.rb | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/oga/xpath/evaluator.rb b/lib/oga/xpath/evaluator.rb index 9372536..f14e6da 100644 --- a/lib/oga/xpath/evaluator.rb +++ b/lib/oga/xpath/evaluator.rb @@ -106,7 +106,26 @@ module Oga end # Filter the nodes based on the predicate. - nodes = process(predicate, nodes) if predicate + if predicate + new_nodes = XML::NodeSet.new + + nodes.each_with_index do |current, index| + xpath_index = index + 1 + # TODO: pass the current node for functions such as position(). + retval = process(predicate, nodes) + + # Non empty node set? Keep the current node + if retval.is_a?(XML::NodeSet) and !retval.empty? + new_nodes << current + + # In case of a number we'll use it as the index. + elsif retval.is_a?(Numeric) && retval.to_i == xpath_index + new_nodes << current + end + end + + nodes = new_nodes + end return nodes end