Skip to content

Commit

Permalink
fix over-eager namespace pruning when reparenting nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
ccutrer authored and codekitchen committed Aug 13, 2015
1 parent 6462d9c commit 093775c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
8 changes: 5 additions & 3 deletions ext/nokogiri/xml_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,11 @@ static void relink_namespace(xmlNodePtr reparented)
reparented->parent,
curr->href
);
/* If we find the namespace is already declared, remove it from this
* definition list. */
if(ns && ns != curr) {
/* If we find the namespace is already declared with the same prefix,
* remove it from this definition list. */
if(ns && ns != curr &&
(ns->prefix == NULL && curr->prefix == NULL ||
xmlStrEqual(ns->prefix, curr->prefix))) {
if (prev) {
prev->next = curr->next;
} else {
Expand Down
40 changes: 40 additions & 0 deletions test/xml/test_node_reparenting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,46 @@ class TestNodeReparenting < Nokogiri::TestCase
assert @doc.at('//foo:second', "foo" => "http://flavorjon.es/")
end
end

describe "and a child node with a namespace matching the parent's non-default namespace, but with a different prefix" do
it "inserts a node that keeps its namespace" do
assert node = @doc.at('//xmlns:first')
child = Nokogiri::XML::Node.new('second', @doc)

ns = child.add_namespace(nil, 'http://flavorjon.es/')
child.namespace = ns

node.add_child(child)
assert newchild = @doc.at('//foo:second', "foo" => "http://flavorjon.es/")
assert newchild.namespace_definitions.include?(ns)
end
end

describe "and a child with an intervening incorrect namespace" do
it "inserts a node that keeps its namespace" do
assert node = @doc.at('//xmlns:first')
child1 = Nokogiri::XML::Node.new('second', @doc)

ns1 = child1.add_namespace('foo', 'bogus')
child1.namespace = ns1

node.add_child(child1)

# Java Nokogiri won't let you add a duplicate (prefix/href) namespace
# if it already exists _anywhere_ in the document; so fudge by
# creating are duplicate in a separate document
doc2 = Nokogiri::XML::Document.new
child2 = Nokogiri::XML::Node.new('third', doc2)
ns2 = child2.add_namespace('foo', 'http://flavorjon.es/')
child2.namespace = ns2

child1.add_child(child2)
assert newchild = @doc.at('//foo:third', "foo" => "http://flavorjon.es/")
# and it also won't find namespace definitions duplicated elsewhere,
# so serialize this check
assert_equal '<foo:third xmlns:foo="http://flavorjon.es/"/>', newchild.to_s
end
end
end
end

Expand Down

0 comments on commit 093775c

Please sign in to comment.