xmlReconciliateNs shifts namespace if a xmlns:default namespace exists
The following code:
#include <string.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
int main() {
const char *input =
"<?xml version=\"1.0\"?>"
"<A xmlns=\"urn:A\">"
"<B>"
"<C xmlns=\"urn:C\" xmlns:default=\"urn:other\"/>"
"</B>"
"</A>";
xmlDocPtr doc = xmlReadMemory(input, strlen(input), NULL, NULL, 0);
if (doc == NULL) {
abort();
}
xmlNodePtr root = xmlDocGetRootElement(doc);
// Make a copy, and reconciliate the namespaces
xmlDocPtr doc2 = xmlNewDoc(NULL);
xmlNodePtr B_copy = xmlDocCopyNode(root->children /* <B> */, doc2, 1);
xmlAddChild((xmlNodePtr) doc2, B_copy);
xmlReconciliateNs(doc2, B_copy);
xmlSaveFormatFileEnc("-", doc2, "UTF-8", 1);
xmlFreeDoc(doc);
xmlFreeDoc(doc2);
return 0;
}
Results in this output:
<?xml version="1.0" encoding="UTF-8"?>
<B xmlns="urn:A" xmlns:default="urn:C">
<default:C xmlns="urn:C" xmlns:default="urn:other"/>
</B>
Notice how the C element is now in the urn:other
namespace instead of urn:C
(the xmlns:default namespace is redeclared on C).
I expected C to still be on the urn:C
namespace instead like in the original document.
I.e. I expected this output (or something equivalent):
<?xml version="1.0" encoding="UTF-8"?>
<B xmlns="urn:A">
<C xmlns="urn:C"/>
</B>
Edited by Nick Wellnhofer