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]