I would add
exclude-result-prefixes="foo"
to your
<xsl:stylesheet>
element. Then the namespace declaration for foo will be omitted if possible, i.e. If there are no elements or attributes in this namespace.
FYI, the reason for this line
<xsl:template match="xsl:stylesheet/@xmlns:foo" />`
throws an error because xmlns:foo in the input document is not an attribute; This is a pseudo attribute. What your matching pattern requests matches an attribute named foo , which is in the namespace matching the xmlns namespace prefix. Since you did not declare the xmlns namespace prefix in your stylesheet, you get the error "xmlns prefix is not defined".
Update:
I see from your published output (and my own testing) that exclude-result-prefixes failed to remove the namespace declaration.
1) First, I would ask why this matters. It does not change the namespace of anything in your output XSLT. Are you just trying to remove it for aesthetic reasons?
2) If you look at the XSLT 1.0 spec, it seems to me that <xsl:copy> does not pay attention to exclude-result-prefixes :
Creating an instance of the xsl: copy element creates a copy of the current node. The namespace nodes of the current node are automatically copied as well ...
AFAICT, only literal result elements will skip namespace nodes based on exclude-result-prefixes .
In this case, I would try to replace <xsl:copy> in your identity template (for elements) with <xsl:element name="{name()}"> or a variant thereof. Then you need a separate identification template for non-element nodes.
I replaced your identity template with the following two templates:
<xsl:template match="*" priority="-1"> <xsl:element name="{name()}"> <xsl:apply-templates select="node()|@*"/> </xsl:element> </xsl:template> <xsl:template match="node()|@*" priority="-2"> <xsl:copy /> </xsl:template>
and this gave what, in my opinion, is the desired result, without extraneous ns declarations:
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:output indent="yes" omit-xml-declaration="yes" /> <xsl:template match="/"> <xsl:variable name="processId" select="''" /> <root> <xsl:apply-templates /> </root> </xsl:template> </xsl:stylesheet>
(I drew a space for clarity.)