From 488000438b8f9822dde01f49ede8033fb8aa6462 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Sun, 20 Jul 2014 07:47:01 +0200 Subject: [PATCH] Support for querying attributes using XPath. --- lib/oga/xpath/evaluator.rb | 18 +++++++++---- spec/oga/xpath/evaluator/axes_spec.rb | 39 +++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/lib/oga/xpath/evaluator.rb b/lib/oga/xpath/evaluator.rb index 94c9543..7983e9a 100644 --- a/lib/oga/xpath/evaluator.rb +++ b/lib/oga/xpath/evaluator.rb @@ -59,11 +59,7 @@ module Oga nodes = XML::NodeSet.new context.each do |xml_node| - # TODO: change this when attribute tests are implemented since those - # are not XML::Element instances. - if xml_node.is_a?(XML::Element) and node_matches?(xml_node, node) - nodes << xml_node - end + nodes << xml_node if node_matches?(xml_node, node) end return nodes @@ -111,6 +107,18 @@ module Oga return nodes end + def on_axis_attribute(node, context) + nodes = XML::NodeSet.new + + context.each do |xml_node| + next unless xml_node.is_a?(XML::Element) + + nodes += on_test(node, xml_node.attributes) + end + + return nodes + end + def child_nodes(nodes) children = XML::NodeSet.new diff --git a/spec/oga/xpath/evaluator/axes_spec.rb b/spec/oga/xpath/evaluator/axes_spec.rb index 015fadb..519c4a6 100644 --- a/spec/oga/xpath/evaluator/axes_spec.rb +++ b/spec/oga/xpath/evaluator/axes_spec.rb @@ -77,4 +77,43 @@ describe Oga::XPath::Evaluator do end end end + + context 'attribute axis' do + before do + document = parse('') + @evaluator = described_class.new(document) + end + + context 'top-level attributes' do + before do + @set = @evaluator.evaluate('attribute::foo') + end + + it_behaves_like :node_set, :length => 1 + + example 'return an Attribute instance' do + @set[0].is_a?(Oga::XML::Attribute).should == true + end + + example 'return the correct attribute' do + @set[0].name.should == 'foo' + end + end + + context 'nested attributes' do + before do + @set = @evaluator.evaluate('/a/attribute::x') + end + + it_behaves_like :node_set, :length => 1 + + example 'return an Attribute instance' do + @set[0].is_a?(Oga::XML::Attribute).should == true + end + + example 'return the correct attribute' do + @set[0].name.should == 'x' + end + end + end end