Skip to content

Commit

Permalink
Add namespace attributes when necessary
Browse files Browse the repository at this point in the history
* ext/java/nokogiri/XmlNode.java (relink_namespace): Add a namespace attribute
  to the new adopted node, if the current scope namespace URI or prefix don't
  match the new node's namespace.

Fixes #1774
  • Loading branch information
jvshahid authored and flavorjones committed Dec 1, 2018
1 parent 543968d commit a4c217c
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 1 deletion.
23 changes: 22 additions & 1 deletion ext/java/nokogiri/XmlNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -472,10 +472,31 @@ public void relink_namespace(ThreadContext context) {
String nsURI = e.lookupNamespaceURI(prefix);
this.node = NokogiriHelpers.renameNode(e, nsURI, e.getNodeName());

if (nsURI == null || nsURI.isEmpty()) {
if (nsURI == null || nsURI == "") {
return;
}

String currentPrefix = e.getParentNode().lookupPrefix(nsURI);
String currentURI = e.getParentNode().lookupNamespaceURI(prefix);
boolean isDefault = e.getParentNode().isDefaultNamespace(nsURI);

// add xmlns attribute if this is a new root node or if the node's
// namespace isn't a default namespace in the new document
if (e.getParentNode().getNodeType() == Node.DOCUMENT_NODE) {
// this is the root node, so we must set the namespaces attributes
// anyway
e.setAttribute(prefix == null ? "xmlns":"xmlns:"+prefix, nsURI);
} else if (prefix == null) {
if (!isDefault)
// this is a default namespace but isn't the default where this
// node is being added
e.setAttribute("xmlns", nsURI);
} else if (currentPrefix != prefix || currentURI != nsURI) {
// this is a prefixed namespace but doens't have the same prefix or
// the prefix is set to a diffent URI
e.setAttribute("xmlns:"+prefix, nsURI);
}

if (e.hasAttributes()) {
NamedNodeMap attrs = e.getAttributes();

Expand Down
53 changes: 53 additions & 0 deletions test/xml/test_node_reparenting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,59 @@ class TestNodeReparenting < Nokogiri::TestCase
node.add_child(child)
assert @doc.at('//xmlns:second')
end

describe "and a child node was added to a new doc with the a different namespace using the same prefix" do
before do
@doc = Nokogiri::XML %Q{<root xmlns:bar="http://tenderlovemaking.com/"><bar:first/></root>}
new_doc = Nokogiri::XML %Q{<newroot xmlns:bar="http://flavorjon.es/"/>}
assert node = @doc.at("//tenderlove:first", tenderlove: "http://tenderlovemaking.com/")
new_doc.root.add_child node
@doc = new_doc
end

it "serializes the doc with the proper default namespace" do
assert_match /<bar:first\ xmlns:bar="http:\/\/tenderlovemaking.com\/"\/>/, @doc.to_xml
end
end

describe "and a child node was added to a new doc with the same default namespaces" do
before do
new_doc = Nokogiri::XML %Q{<newroot xmlns="http://tenderlovemaking.com/"/>}
assert node = @doc.at("//tenderlove:first", tenderlove: "http://tenderlovemaking.com/")
new_doc.root.add_child node
@doc = new_doc
end

it "serializes the doc with the proper default namespace" do
assert_match /<first>/, @doc.to_xml
end
end

describe "and a child node was added to a new doc without any default namespaces" do
before do
new_doc = Nokogiri::XML "<newroot/>"
assert node = @doc.at("//tenderlove:first", tenderlove: "http://tenderlovemaking.com/")
new_doc.root.add_child node
@doc = new_doc
end

it "serializes the doc with the proper default namespace" do
assert_match /<first xmlns=\"http:\/\/tenderlovemaking.com\/\">/, @doc.to_xml
end
end

describe "and a child node became the root of a new doc" do
before do
new_doc = Nokogiri::XML::Document.new
assert node = @doc.at("//tenderlove:first", tenderlove: "http://tenderlovemaking.com/")
new_doc.root = node
@doc = new_doc
end

it "serializes the doc with the proper default namespace" do
assert_match /<first xmlns=\"http:\/\/tenderlovemaking.com\/\">/, @doc.to_xml
end
end
end

describe "given a parent node with a default and non-default namespace" do
Expand Down

0 comments on commit a4c217c

Please sign in to comment.