XSL - copy elements but remove unused namespace(s)
xml-namespaces, xslt
Solution
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:x="http://tempuri.com">
<xsl:template match="/">
<xsl:apply-templates select="/a/b"/>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name(.)}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:copy/>
</xsl:template>
<!-- This empty template is not needed.
Neither is the xmlns declaration above:
<xsl:template match="@x:*"/> -->
</xsl:stylesheet>
I found an explanation here.
Michael Kay wrote: exclude-result-prefixes only affects the namespaces copied from the stylesheet by a literal result element, it doesn't affect copying of namespaces from source documents.
Problem
I've got some XML which declares a namespace which is only used for attributes, like this: ``` <?xml version="1.0" encoding="UTF-8"?> <a xmlns:x="http://tempuri.com"> <b> <c x:att="true"/> <d>hello</d> </b> </a> ``` I want to use XSL to create a copy of selected nodes and their values - getting rid of the attributes. So my desired output is: ``` <?xml version="1.0" encoding="UTF-8"?> <b> <c /> <d>hello</d> </b> ``` I've got some XSL that almost does this, but I can't seem to stop it putting the namespace declaration in the top level element of the output. My XSL is: ``` <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/"> <xsl:apply-templates select="/a/b"/> </xsl:template> <xsl:template match="node()"> <xsl:copy> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet> ``` The first element of the output is `<b xmlns:x="http://tempuri.com">` instead of `<b>`. I've tried declaring the namespace in the XSL and putting the prefix in the `exclude-result-prefixes` list, but this doesn't seem to have any effect. What am I doing wrong? UPDATE: I've found that by declaring the namespace in the XSL and using the `extension-element-prefixes` attribute works, but this doesn't seem right! I guess I could use this, but I'd like to know why the `exclude-result-prefixes` doesn't work! UPDATE: Actually, it seems this `extension-element-prefixes` solution only works with XMLSpy's built-in XSLT engine, not with MSXML.