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) | ||||
|       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. | ||||
|  |  | |||
|  | @ -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