GNOME Bugzilla – Bug 614068
xmlReplaceNode sometimes adds unnecessary namespace declaration
Last modified: 2010-03-28 14:56:19 UTC
(I will demonstrate this problem with the XML::LibXML Perl bindings, because they make the code simpler to write. I believe from what I see that the Perl bindings are not at fault and they just call libxml2's xmlReplaceNode() faithfully. My apologies if this assumption is wrong.) Consider the following program, which attempts to create an element node ("bar") in a given namespace, and then replace it by another created element node ("baz") in the same namespace: #! /usr/local/bin/perl -w require 5.10.0; use strict; use warnings; use XML::LibXML; my $parser = XML::LibXML->new(); my $doc = $parser->parse_string(<<'__EOF__'); <?xml version="1.0" encoding="utf-8"?> <f:foo xmlns:f="http://www.example.tld/f/" xmlns="http://www.example.tld/b/"><barf/></f:foo> __EOF__ my $foo = $doc->documentElement; my $bar = $doc->createElementNS("http://www.example.tld/b/", "bar"); $foo->appendChild($bar); my $baz = $doc->createElementNS("http://www.example.tld/b/", "baz"); $bar->replaceNode($baz); # This calls xmlReplaceNode($bar,$baz) print $doc->toString; The output is this: <?xml version="1.0" encoding="utf-8"?> <f:foo xmlns:f="http://www.example.tld/f/" xmlns="http://www.example.tld/b/"><barf/><baz xmlns="http://www.example.tld/b/"/></f:foo> It's not wrong, but the xmlns attribute on the "baz" element is unnecessary. (Alas, this can cause validation problems when the DTD does not permit such a liberty. That's how I found this.) Strangely enough, removing the seemingly unrelated "barf" element from the initial document makes the issue go away. Also, removing the call to replaceNode() (leaving the bar element as it was created) does not exhibit the problem. A workaround is to call $foo->appendChild($baz) before $bar->replaceNode($baz) (in this trivial example it doesn't make much sense, of course, but in a more complex case it might matter).
Bug has disappeared in recent versions of libxml2 or XML::LibXML - closing. Sorry about the noise.