Support for the XPath "following" axis.

This commit is contained in:
Yorick Peterse 2014-07-29 23:09:16 +02:00
parent 023e7c6583
commit 9a97d936e3
2 changed files with 76 additions and 0 deletions

View File

@ -241,6 +241,35 @@ module Oga
return on_test(node, context) + on_axis_descendant(node, context)
end
##
# Evaluates the `following` axis.
#
# @param [Oga::XPath::Node] node
# @param [Oga::XML::NodeSet] context
# @return [Oga::XML::NodeSet]
#
def on_axis_following(node, context)
nodes = XML::NodeSet.new
context.each do |context_node|
current = context_node
while current.respond_to?(:next)
next_node = current.next
if can_match_node?(next_node) and node_matches?(next_node, node)
nodes << next_node
end
# When this returns nil the loop automaticall breaks since `nil`
# doesn't respond to `next`.
current = next_node
end
end
return nodes
end
##
# Returns a node set containing all the child nodes of the given set of
# nodes.

View File

@ -0,0 +1,47 @@
require 'spec_helper'
describe Oga::XPath::Evaluator do
context 'following axis' do
before do
document = parse('<a><b></b><c></c><c></c></a>')
@first_c = document.children[0].children[1]
@second_c = document.children[0].children[2]
@evaluator = described_class.new(document)
end
# This should return an empty set since the document doesn't have any
# following nodes.
context 'using a document as the root' do
before do
@set = @evaluator.evaluate('following::a')
end
it_behaves_like :empty_node_set
end
context 'matching following elements using a name' do
before do
@set = @evaluator.evaluate('a/b/following::c')
end
it_behaves_like :node_set, :length => 2
example 'return the first <c> node' do
@set[0].should == @first_c
end
example 'return the second <c> node' do
@set[1].should == @second_c
end
end
context 'matching following elements using a wildcard' do
before do
@set = @evaluator.evaluate('a/b/following::*')
end
it_behaves_like :node_set, :length => 2
end
end
end