Support for the XPath "following" axis.
This commit is contained in:
		
							parent
							
								
									023e7c6583
								
							
						
					
					
						commit
						9a97d936e3
					
				|  | @ -241,6 +241,35 @@ module Oga | ||||||
|         return on_test(node, context) + on_axis_descendant(node, context) |         return on_test(node, context) + on_axis_descendant(node, context) | ||||||
|       end |       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 |       # Returns a node set containing all the child nodes of the given set of | ||||||
|       # nodes. |       # nodes. | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
		Loading…
	
		Reference in New Issue