XSLT: Clean up duplicate namespaces and namespace declarations
Published:
I got an XML file from a web service which had a default namespace and a namespace prefix with equal paths. In addition I had to change the root node which then lost all its defined namespaces. This resulted in various namespaces being redeclared on a bunch of various child elements, while it really should just need to be declared once on the root node.
So, this is how you may do fix this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://api.example.com/schema"
xmlns:dup="http://api.example.com/schema">
<!-- Identity template, copies everything -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<!-- Make all elements with dup prefix use default namespace so we avoid ugly mix of both -->
<xsl:template match="dup:*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@* | node()" />
</xsl:element>
</xsl:template>
<!-- For the document element (top element) -->
<xsl:template match="/*">
<xsl:copy>
<!-- Add namespace to prevent redeclaration on every child element using it -->
<xsl:namespace name="xsi" select="'http://www.w3.org/2001/XMLSchema-instance'" />
<!-- Copy attributes and child elements -->
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>