Skip to content

Commit 7e38303

Browse files
committed
fix(cruby): reconciliation of ns on unparented nodes
Closes #3459
1 parent 3ff6b8e commit 7e38303

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

ext/nokogiri/xml_node.c

+4
Original file line numberDiff line numberDiff line change
@@ -1334,6 +1334,10 @@ set_namespace(VALUE self, VALUE namespace)
13341334

13351335
xmlSetNs(node, ns);
13361336

1337+
if (ns && ns->prefix) {
1338+
xmlReconciliateNs(node->doc, node);
1339+
}
1340+
13371341
return self;
13381342
}
13391343

test/xml/test_node.rb

+13
Original file line numberDiff line numberDiff line change
@@ -1336,6 +1336,19 @@ def test_namespace_in_rendered_xml
13361336
assert_match(/xmlns="bar"/, subject.to_xml)
13371337
end
13381338

1339+
# https://github.com/sparklemotion/nokogiri/issues/3459
1340+
def test_namespace_set_on_unparented_node_also_sets_a_definition
1341+
doc = Nokogiri::XML(%{<root xmlns:foo="http://example.com/foo"></root>})
1342+
ns = doc.root.namespace_definitions.first
1343+
1344+
node = doc.create_element("other")
1345+
node.namespace = ns
1346+
1347+
assert_pattern do
1348+
node.namespace_definitions => [ { prefix: "foo", href: "http://example.com/foo" } ]
1349+
end
1350+
end
1351+
13391352
# issue 771
13401353
def test_format_noblank
13411354
content = <<~XML

test/xml/test_node_reparenting.rb

+23
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,29 @@ def coerce(data)
845845
end
846846
end
847847
end
848+
849+
# https://github.com/sparklemotion/nokogiri/issues/3459
850+
describe "reparenting with duplicate namespace prefixes" do
851+
it "stitches together ok" do
852+
doc = Nokogiri::XML(<<~XML)
853+
<dnd:adventure xmlns:dnd="http://www.w3.org/dungeons#">
854+
<dnd:party xmlns:dnd="http://www.w3.org/dragons#">
855+
<dnd:members>
856+
</dnd:members>
857+
</dnd:party>
858+
</dnd:adventure>
859+
XML
860+
861+
dungeons_ns = doc.root.namespace_definitions.find { |ns| ns.prefix == "dnd" }
862+
parent = doc.xpath("//ns:members", ns: "http://www.w3.org/dragons#").first
863+
864+
node = doc.create_element("character")
865+
node.namespace = dungeons_ns
866+
parent.add_child(node)
867+
868+
assert_includes(doc.to_xml, %{<dnd:character xmlns:dnd="http://www.w3.org/dungeons#"/>})
869+
end
870+
end
848871
end
849872
end
850873
end

0 commit comments

Comments
 (0)