I have an XSLT stylesheet like the following:
I would add
exclude-result-prefixes="foo"
onto your
<xsl:stylesheet>
element. Then the namespace declaration for foo
will be omitted if possible, i.e. if there no elements or attributes in that namespace to output.
FYI, the reason tnat this line
<xsl:template match="xsl:stylesheet/@xmlns:foo" />`
throws an error is because xmlns:foo
in the input document is not an attribute; it's a pseudoattribute. What your match pattern is asking to match is an attribute named foo
that is in a namespace corresponding to a namespace prefix xmlns
. Since you have not declared a namespace prefix xmlns
in your stylesheet, you get the error "prefix xmlns is not defined."
I see from your posted output (and my own testing) that exclude-result-prefixes
hasn't been effective in removing the namespace declaration.
1) First I would ask why it matters. It doesn't change the namespace of anything in your output XSLT. Are you just trying to remove it for aesthetic reasons?
2) Looking at the XSLT 1.0 spec, it appears to me that <xsl:copy>
pays no attention to exclude-result-prefixes
:
Instantiating 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 omit namespace nodes based on exclude-result-prefixes
.
On that basis, I would try replacing <xsl:copy>
in your identity template (for elements) with <xsl:element name="{name()}">
or some variant thereof. You would then need a separate identity template for non-element nodes.
I replaced your identity template with the following two templates:
<!-- Copy elements -->
<xsl:template match="*" priority="-1">
<xsl:element name="{name()}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<!-- Copy all other nodes -->
<xsl:template match="node()|@*" priority="-2">
<xsl:copy />
</xsl:template>
and that gave what I believe is the desired output, with no 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>
<!-- Other stuff -->
</xsl:stylesheet>
(I have adjusted the whitespace for clarity.)