GNOME Bugzilla – Bug 344176
xsl:copy misses to set an element's namespace-URI in some cases
Last modified: 2006-06-19 18:32:12 UTC
The instruction xsl:copy will miss to set an element node's namespace-URI in some cases; the resulting element will be put incorrectly into the NULL namespace. Example: stylesheet ---------- <?xml version='1.0'?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:f="urn:test:foo" xmlns:ex="http://exslt.org/common"> <xsl:template match="f:foo"> <xsl:variable name="foo"> <xsl:copy> <xsl:copy-of select="."/> </xsl:copy> </xsl:variable> <xsl:value-of select="count(ex:node-set($foo)/foo)"/> <xsl:value-of select="count(ex:node-set($foo)/f:foo)"/> </xsl:template> </xsl:stylesheet> source doc ---------- <?xml version="1.0"?> <foo xmlns:bar="urn:test:bar" xmlns="urn:test:foo"/> xsltproc result --------------- xsltproc xsl-copy.xsl xsl-copy.xml <?xml version="1.0"?> 10 Expected result --------------- <?xml version="1.0"?> 01 (Note that I used a count/select on the copied elements in the example, since if simply xsl:copying/serializing the resulting XML does not indicate that we loose the namespace assignment. Also xsltproc's --dump option won't help to examine if the copy of the "foo" element is in the default or the NULL namespace, since xmlCtxtDumpOneNode() does not indicate if elements are in the default namespace.) The problem is located in xsltGetNamespace(), where a fix for bug #165560 produces the incorrect behaviour as a side-effect: xsltCopy() --> xsltCopyNode() --> xsltGetNamespace() The following code will try to redeclare the same namespace-URI with no prefix on the result-element with xmlNewNs(); this will return NULL, which is then assigned to node->ns of the resulting element. if (out->type == XML_ELEMENT_NODE) { if ((ret == NULL) || ((ret->prefix == NULL) && (out->ns == NULL) && (out->nsDef != NULL) && (!xmlStrEqual(URI, out->nsDef->href)))) { ret = xmlNewNs(out, URI, ns->prefix); } }
Fixed in CVS HEAD. Current result: <?xml version="1.0"?> 01