diff --git a/lib/rexml/element.rb b/lib/rexml/element.rb
index a002db07..394d7415 100644
--- a/lib/rexml/element.rb
+++ b/lib/rexml/element.rb
@@ -1269,20 +1269,17 @@ def [](name_or_index)
# document.root.attribute("x", "a") # => a:x='a:x'
#
def attribute( name, namespace=nil )
- prefix = namespaces.key(namespace) if namespace
- prefix = nil if prefix == 'xmlns'
-
- ret_val =
- attributes.get_attribute( prefix ? "#{prefix}:#{name}" : name )
+ return attributes.get_attribute( name ) if namespace.nil?
+ ret_val = attributes.get_attribute_ns( namespace, name )
return ret_val unless ret_val.nil?
- return nil if prefix.nil?
-
- # now check that prefix'es namespace is not the same as the
- # default namespace
- return nil unless ( namespaces[ prefix ] == namespaces[ 'xmlns' ] )
- attributes.get_attribute( name )
+ # Kept for compatibility: an unprefixed attribute also matches when the
+ # requested URI is the default namespace or is not declared on this
+ # element, even though such an attribute is not in that namespace.
+ if namespace == namespaces[ 'xmlns' ] or !namespaces.has_value?( namespace )
+ attributes.get_attribute( name )
+ end
end
# :call-seq:
diff --git a/test/test_element.rb b/test/test_element.rb
index 20216895..02dae3be 100644
--- a/test/test_element.rb
+++ b/test/test_element.rb
@@ -11,5 +11,33 @@ def test_array_reference_symbol
doc = REXML::Document.new("")
assert_equal("Ruby", doc.root[:name])
end
+
+ def test_attribute_duplicated_namespace_url
+ doc = REXML::Document.new("")
+ root = doc.root
+ attributes = [
+ root.attribute("a", "url1"),
+ root.attribute("b", "url1"),
+ root.attribute("c", "url2"),
+ root.attribute("d", "url2"),
+ ]
+ assert_equal(["ns1:a", "ns1:b", "ns2:c", "ns3:d"],
+ attributes.collect {|attribute| attribute&.expanded_name})
+ end
+
+ def test_attribute_prefixed_match_independent_of_declaration_order
+ sources = [
+ "",
+ "",
+ "",
+ "",
+ ]
+ expanded_names = sources.collect do |source|
+ REXML::Document.new(source).root.attribute("a", "url1").expanded_name
+ end
+ assert_equal(["ns1:a"] * 4, expanded_names)
+ end
end
end