diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d723481f2..c6d7e39861 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ Nokogiri follows [Semantic Versioning](https://semver.org/), please see the [REA * [CRuby] libgumbo (the HTML5 parser) treats reaching max-depth as EOF. This addresses a class of issues when the parser is interrupted in this way. [#3121] @stevecheckoway * [CRuby] Update node GC lifecycle to avoid a potential memory leak with fragments in libxml 2.13.0 caused by changes in `xmlAddChild`. [#3156] @flavorjones * [CRuby] libgumbo correctly prints nonstandard element names in error messages. [#3219] @stevecheckoway +* [JRuby] Fixed some bugs in how `Node#attributes` handles attributes with namespaces. [#2677, #2679] @flavorjones ### Changed diff --git a/ext/java/nokogiri/XmlNode.java b/ext/java/nokogiri/XmlNode.java index 4ecc957954..70440b5351 100644 --- a/ext/java/nokogiri/XmlNode.java +++ b/ext/java/nokogiri/XmlNode.java @@ -643,12 +643,22 @@ public class XmlNode extends RubyObject @JRubyMethod(name = {"attribute", "attr"}) public IRubyObject - attribute(ThreadContext context, IRubyObject name) + attribute(ThreadContext context, IRubyObject rbName) { - NamedNodeMap attrs = this.node.getAttributes(); - Node attr = attrs.getNamedItem(rubyStringToString(name)); - if (attr == null) { return context.nil; } - return getCachedNodeOrCreate(context.runtime, attr); + NamedNodeMap attributes = this.node.getAttributes(); + String name = rubyStringToString(rbName); + + for (int j = 0 ; j < attributes.getLength() ; j++) { + Node attribute = attributes.item(j); + String localName = attribute.getLocalName(); + if (localName == null) { + continue; + } + if (localName.equals(name)) { + return getCachedNodeOrCreate(context.runtime, attribute); + } + } + return context.nil; } @JRubyMethod @@ -1415,11 +1425,12 @@ public class XmlNode extends RubyObject } } - if (uri != null) { - element.setAttributeNS(uri, key, val); - } else { + if (colonIndex > 0 && uri == null) { element.setAttribute(key, val); + } else { + element.setAttributeNS(uri, key, val); } + clearXpathContext(node); }