After scouring the net for answers, coming up with “almost” solutions… I decided to reduce the problem to a very simple case.
Consider the following XML snippet:
<me:root xmlns:me="http://stackoverflow.com/xml"
xmlns="http://www.w3.org/1999/xhtml">
<me:element>
<p>Some HTML code here.</p>
</me:element>
</me:root>
Note that the p element is of XHTML’s namespace, which is the default one for this doc.
Now consider the following simple stylesheet. I want to create an XHTML document, with the contents of me:element as the body.
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:me="http://stackoverflow.com/xml"
xmlns="http://www.w3.org/1999/xhtml"
exclude-result-prefixes="me">
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My Title</title>
</head>
<body>
<xsl:copy-of select="me:root/me:element/node()"/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Note that I included exclude-result-prefixes… But see what I get:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My Title</title>
</head>
<body>
<p xmlns:me="http://stackoverflow.com/xml">Some HTML code here.</p>
</body>
</html>
And what’s driving me insane here is why, oh why does xmlns:me appears inside the p element?
No matter what I tried, I couldn’t get stuff to work. I have a strange feeling that the problem is with my xsl:copy-of statement.
This is exactly the reason.
The source XML document contains this fragment:
In the XPath data model, namespace nodes are propagated from a root of a subtree to all of its descendents. Therefore, the
<p>element has the following namespaces:"http://www.w3.org/1999/xhtml""http://stackoverflow.com/xml""http://www.w3.org/XML/1998/namespace"http://www.w3.org/2000/xmlns/The last two are reserved namespaces (for the prefixes
xml:andxmlns) and are available to any named node.The reported problem is due to the fact that by definition the
<xsl:copy-of>instruction copies all nodes and their complete subtrees with all namespaces belonging to each of the nodes.Remember: the prefixes specified as the value of the
exclude-result-prefixesattribute are excluded only from literal-result elements!Solution:
when this transformation is applied on the provided XML document:
the wanted, correct result is produced: