From b304b8b077059c31b55e782b050e993ce70b91a4 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Thu, 23 Oct 2014 01:12:10 +0200 Subject: [PATCH] Fixed descendant-or-self with a predicate. Processing of this axis along with a predicate wouldn't quite work out. Even if the predicate returned false the node would still be matched (which should not be the case). --- lib/oga/xpath/evaluator.rb | 6 +---- .../evaluator/axes/descendant_or_self_spec.rb | 26 ++++++++++++++++++- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/lib/oga/xpath/evaluator.rb b/lib/oga/xpath/evaluator.rb index 0bb36ee..d173b77 100644 --- a/lib/oga/xpath/evaluator.rb +++ b/lib/oga/xpath/evaluator.rb @@ -319,12 +319,8 @@ module Oga nodes = XML::NodeSet.new context.each do |context_node| - context_node.children.each do |node| - nodes << node if node_matches?(node, ast_node) - end - context_node.each_node do |node| - nodes << node if node_matches?(node, ast_node) + nodes.concat(process(ast_node, XML::NodeSet.new([node]))) end end diff --git a/spec/oga/xpath/evaluator/axes/descendant_or_self_spec.rb b/spec/oga/xpath/evaluator/axes/descendant_or_self_spec.rb index 5baf389..081c988 100644 --- a/spec/oga/xpath/evaluator/axes/descendant_or_self_spec.rb +++ b/spec/oga/xpath/evaluator/axes/descendant_or_self_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe Oga::XPath::Evaluator do context 'descendant-or-self axis' do before do - document = parse('') + document = parse('') @first_a = document.children[0] @first_b = @first_a.children[0] @@ -40,6 +40,14 @@ describe Oga::XPath::Evaluator do end end + context 'nested descendants with a matching predicate' do + before do + @set = @evaluator.evaluate('descendant-or-self::c[@class="x"]') + end + + it_behaves_like :node_set, :length => 1 + end + context 'descendants of a specific node' do before do @set = @evaluator.evaluate('a/descendant-or-self::b') @@ -88,6 +96,22 @@ describe Oga::XPath::Evaluator do it_behaves_like :empty_node_set end + context 'direct descendants without a matching predicate' do + before do + @set = @evaluator.evaluate('descendant-or-self::a[@class]') + end + + it_behaves_like :empty_node_set + end + + context 'nested descendants without a matching predicate' do + before do + @set = @evaluator.evaluate('descendant-or-self::b[@class]') + end + + it_behaves_like :empty_node_set + end + context 'direct descendants using the short form' do before do @set = @evaluator.evaluate('//b')