diff --git a/lib/oga/xpath/compiler.rb b/lib/oga/xpath/compiler.rb index 265e672..e51f769 100644 --- a/lib/oga/xpath/compiler.rb +++ b/lib/oga/xpath/compiler.rb @@ -142,11 +142,12 @@ module Oga # @param [Oga::Ruby::Node] input # @return [Oga::Ruby::Node] def on_axis_child(ast, input) - child = unique_literal(:child) - condition = process(ast, child) + child = unique_literal(:child) - input.children.each.add_block(child) do - condition.if_true { yield child } + document_or_node(input).if_true do + input.children.each.add_block(child) do + process(ast, child).if_true { yield child } + end end end @@ -155,7 +156,7 @@ module Oga # @return [Oga::Ruby::Node] def on_axis_attribute(ast, input) input.is_a?(XML::Element).if_true do - attribute = literal(:attribute) + attribute = unique_literal(:attribute) input.attributes.each.add_block(attribute) do name_match = match_name_and_namespace(ast, attribute) @@ -178,7 +179,7 @@ module Oga process(ast, input) .if_true { yield input } .followed_by do - node_or_attribute(input).if_true do + attribute_or_node(input).if_true do input.each_ancestor.add_block(parent) do process(ast, parent).if_true { yield parent } end @@ -192,7 +193,7 @@ module Oga def on_axis_ancestor(ast, input) parent = unique_literal(:parent) - node_or_attribute(input).if_true do + attribute_or_node(input).if_true do input.each_ancestor.add_block(parent) do process(ast, parent).if_true { yield parent } end @@ -1367,15 +1368,21 @@ module Oga # @param [Oga::Ruby::Node] node # @return [Oga::Ruby::Node] def element_or_attribute(node) - node.is_a?(XML::Attribute).or(node.is_a?(XML::Element)) + node.is_a?(XML::Element).or(node.is_a?(XML::Attribute)) end # @param [Oga::Ruby::Node] node # @return [Oga::Ruby::Node] - def node_or_attribute(node) + def attribute_or_node(node) node.is_a?(XML::Attribute).or(node.is_a?(XML::Node)) end + # @param [Oga::Ruby::Node] node + # @return [Oga::Ruby::Node] + def document_or_node(node) + node.is_a?(XML::Document).or(node.is_a?(XML::Node)) + end + # @param [AST::Node] ast # @param [Oga::Ruby::Node] input # @return [Oga::Ruby::Node] diff --git a/spec/oga/xpath/compiler/axes/attribute_spec.rb b/spec/oga/xpath/compiler/axes/attribute_spec.rb index adbeebc..c669951 100644 --- a/spec/oga/xpath/compiler/axes/attribute_spec.rb +++ b/spec/oga/xpath/compiler/axes/attribute_spec.rb @@ -1,24 +1,44 @@ require 'spec_helper' describe Oga::XPath::Compiler do - describe 'attribute axis' do - before do - @document = parse('') + before do + @document = parse('') - @a1 = @document.children[0] - @attr = @a1.attribute('foo') + @a1 = @document.children[0] + @attr = @a1.attribute('foo') + end + + describe 'relative to a document' do + describe 'attribute::foo' do + it 'returns an empty NodeSet' do + evaluate_xpath(@document).should == node_set + end + end + end + + describe 'relative to an element' do + describe 'attribute::foo' do + it 'returns a NodeSet' do + evaluate_xpath(@a1).should == node_set(@attr) + end end - it 'returns a node set containing an attribute' do - evaluate_xpath(@a1, 'attribute::foo').should == node_set(@attr) + describe '@foo' do + it 'returns a NodeSet' do + evaluate_xpath(@a1).should == node_set(@attr) + end end - it 'returns a node set containing an attribute using the short form' do - evaluate_xpath(@a1, '@foo').should == node_set(@attr) + describe 'attribute::bar' do + it 'returns an empty NodeSet' do + evaluate_xpath(@a1).should == node_set + end end - it 'returns an empty node set for non existing attributes' do - evaluate_xpath(@a1, 'attribute::bar').should == node_set + describe 'attribute::foo/bar' do + it 'returns an empty NodeSet' do + evaluate_xpath(@a1).should == node_set + end end end end