diff --git a/lib/oga/xml/document.rb b/lib/oga/xml/document.rb index ae82630..9a995ee 100644 --- a/lib/oga/xml/document.rb +++ b/lib/oga/xml/document.rb @@ -89,6 +89,23 @@ module Oga end end + ## + # Returns the available namespaces. These namespaces are retrieved from + # the first element in the document. + # + # @see [Oga::XML::Element#available_namespaces] + # + def available_namespaces + children.each do |child| + # There's no guarantee that the first node is *always* an element + # node. + return child.available_namespaces if child.is_a?(Element) + end + + # In case the document is empty. + return {} + end + ## # Converts the document and its child nodes to XML. # diff --git a/lib/oga/xpath/evaluator.rb b/lib/oga/xpath/evaluator.rb index c2b6bfe..148c79a 100644 --- a/lib/oga/xpath/evaluator.rb +++ b/lib/oga/xpath/evaluator.rb @@ -410,7 +410,11 @@ module Oga name = ast_node.children[1] context.each do |context_node| - + context_node.available_namespaces.each do |_, namespace| + if namespace.name == name or name == '*' + nodes << namespace + end + end end return nodes diff --git a/spec/oga/xml/document_spec.rb b/spec/oga/xml/document_spec.rb index 5c68e5c..e475b85 100644 --- a/spec/oga/xml/document_spec.rb +++ b/spec/oga/xml/document_spec.rb @@ -71,6 +71,20 @@ describe Oga::XML::Document do end end + context '#available_namespaces' do + example 'return an empty Hash by default' do + described_class.new.available_namespaces.should be_empty + end + + example 'return the namespaces of the first element' do + namespace = Oga::XML::Namespace.new(:name => 'x') + element = Oga::XML::Element.new(:namespaces => {'x' => namespace}) + document = described_class.new(:children => [element]) + + document.available_namespaces['x'].should == namespace + end + end + context '#to_xml' do before do child = Oga::XML::Comment.new(:text => 'foo') diff --git a/spec/oga/xpath/evaluator/axes/namespace_spec.rb b/spec/oga/xpath/evaluator/axes/namespace_spec.rb index 6df1acb..72797fd 100644 --- a/spec/oga/xpath/evaluator/axes/namespace_spec.rb +++ b/spec/oga/xpath/evaluator/axes/namespace_spec.rb @@ -12,6 +12,14 @@ describe Oga::XPath::Evaluator do @evaluator = described_class.new(@document) end + context 'matching namespaces in the entire document' do + before do + @set = @evaluator.evaluate('namespace::*') + end + + it_behaves_like :empty_node_set + end + context 'matching namespaces in the root element' do before do @set = @evaluator.evaluate('root/namespace::x') @@ -30,17 +38,17 @@ describe Oga::XPath::Evaluator do context 'matching namespaces in a nested element' do before do - @set = @evaluator.evaluate('root/namespace::x') + @set = @evaluator.evaluate('root/foo/namespace::*') end it_behaves_like :node_set, :length => 2 - example 'return the "x" namespace' do - @set[0].name.should == 'x' + example 'return the "y" namespace' do + @set[0].name.should == 'y' end - example 'return the "y" namespace' do - @set[1].name.should == 'y' + example 'return the "x" namespace' do + @set[1].name.should == 'x' end end