diff --git a/lib/oga/xml/element.rb b/lib/oga/xml/element.rb index 054f864..3af4847 100644 --- a/lib/oga/xml/element.rb +++ b/lib/oga/xml/element.rb @@ -144,7 +144,13 @@ module Oga # @return [Oga::XML::Namespace] # def namespace - return @namespace ||= available_namespaces[namespace_name] + unless @namespace + available = available_namespaces + + @namespace = available[namespace_name] || available[XMLNS_PREFIX] + end + + return @namespace end ## @@ -283,7 +289,14 @@ module Oga self.attributes = attributes.reject do |attr| # We're using `namespace_name` opposed to `namespace.name` as "xmlns" # is not a registered namespace. - remove = attr.namespace_name && attr.namespace_name == XMLNS_PREFIX + remove = attr.name == XMLNS_PREFIX || + attr.namespace_name == XMLNS_PREFIX + + # If the attribute sets the default namespace we'll also overwrite the + # namespace_name. + if attr.name == XMLNS_PREFIX + @namespace_name = XMLNS_PREFIX + end register_namespace(attr.name, attr.value) if remove diff --git a/spec/oga/xml/element_spec.rb b/spec/oga/xml/element_spec.rb index 6c561ae..416e4a0 100644 --- a/spec/oga/xml/element_spec.rb +++ b/spec/oga/xml/element_spec.rb @@ -34,6 +34,22 @@ describe Oga::XML::Element do end end + context 'setting the default namespace without a prefix' do + before do + attr = Oga::XML::Attribute.new(:name => 'xmlns', :value => 'foo') + + @element = described_class.new(:attributes => [attr]) + end + + example 'register the default namespace' do + @element.namespaces['xmlns'].is_a?(Oga::XML::Namespace).should == true + end + + example 'remove the namespace attribute from the list of attributes' do + @element.attributes.empty?.should == true + end + end + context '#attribute' do before do attributes = [ @@ -159,16 +175,23 @@ describe Oga::XML::Element do end context '#namespace' do - before do - @namespace = Oga::XML::Namespace.new(:name => 'x') - @element = described_class.new( + example 'return the namespace' do + namespace = Oga::XML::Namespace.new(:name => 'x') + element = described_class.new( :namespace_name => 'x', - :namespaces => {'x' => @namespace} + :namespaces => {'x' => namespace} ) + + element.namespace.should == namespace end - example 'return the namespace' do - @element.namespace.should == @namespace + example 'return the default namespace if available' do + namespace = Oga::XML::Namespace.new(:name => 'xmlns') + element = described_class.new( + :namespaces => {'xmlns' => namespace} + ) + + element.namespace.should == namespace end end diff --git a/spec/oga/xml/parser/elements_spec.rb b/spec/oga/xml/parser/elements_spec.rb index afe317f..37ca966 100644 --- a/spec/oga/xml/parser/elements_spec.rb +++ b/spec/oga/xml/parser/elements_spec.rb @@ -37,6 +37,31 @@ describe Oga::XML::Parser do end end + context 'elements with default namespaces' do + before :all do + @document = parse('') + + @foo = @document.children[0] + @bar = @foo.children[0] + end + + example 'set the namespace name of the element' do + @foo.namespace.name.should == 'xmlns' + end + + example 'set the namespace URI of the element' do + @foo.namespace.uri.should == 'bar' + end + + example 'set the namespace name of the element' do + @bar.namespace.name.should == 'xmlns' + end + + example 'set the namespace URI of the element' do + @bar.namespace.uri.should == 'bar' + end + end + context 'elements with attributes' do before :all do @element = parse('').children[0]