After searching for a while i figured I'd ask here. I'm trying to remove the empty namespace from an XSL output file. Let me provide the relevant code:
Input XML
<?xml version="1.0" encoding="UTF-8"?>
<DK_RequestChangeOfSupplier xmlns="un:unece:260:data:EEM-DK_RequestChangeOfSupplier:v2">
<HeaderEnergyDocument>
<Creation>Date</Creation>
</HeaderEnergyDocument>
</DK_RequestChangeOfSupplier>
XSL
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="un:unece:260:data:EEM-DK_RequestChangeOfSupplier:v2"
exclude-result-prefixes="ns1">
<xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="yes" omit-xml-declaration="no"/>
<xsl:template match="/">
<xsl:for-each select="ns1:DK_RequestChangeOfSupplier">
<McsDkSMBMsg
xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/McsDkSMBMsg">
<xsl:call-template name="CreateElement">
<xsl:with-param name="ElementName" select="'Creation'" />
</xsl:call-template>
</McsDkSMBMsg>
</xsl:for-each>
</xsl:template>
<xsl:template name="CreateElement">
<xsl:param name="ElementName"></xsl:param>
<xsl:element name="{$ElementName}">Testing</xsl:element>
</xsl:template>
</xsl:stylesheet>
Output
<McsDkSMBMsg xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/McsDkSMBMsg">
<Creation xmlns="">Testing</Creation>
</McsDkSMBMsg>
How do I remove the namespace? Am I doing something completely wrong XSL-wise? I'm slowly pulling my hair out. Regards.
Your original code adds two elements to the output tree: One called McsDkSMBMsg
which has a default namespace:
<McsDkSMBMsg xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/McsDkSMBMsg">
the other one is Creation
- which, according to your original code, is in no namespace at all. The only way for the XSLT processor to ensure that the Creation
element does not end up in the default namespace is to undeclare this namespace:
<Creation xmlns="">Testing</Creation>
I assume you'd like the Creation
element to also belong to that default namespace. If so, simply add the same xmlns
attribute to the xsl:element
instruction where Creation
is created. The XLST processor will take care of any redundant namespace declarations.
Stylesheet
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="un:unece:260:data:EEM-DK_RequestChangeOfSupplier:v2"
exclude-result-prefixes="ns1">
<xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="yes" omit-xml-declaration="no"/>
<xsl:template match="/">
<xsl:for-each select="ns1:DK_RequestChangeOfSupplier">
<McsDkSMBMsg
xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/McsDkSMBMsg">
<xsl:call-template name="CreateElement">
<xsl:with-param name="ElementName" select="'Creation'" />
</xsl:call-template>
</McsDkSMBMsg>
</xsl:for-each>
</xsl:template>
<xsl:template name="CreateElement">
<xsl:param name="ElementName"></xsl:param>
<xsl:element name="{$ElementName}" xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/McsDkSMBMsg">Testing</xsl:element>
</xsl:template>
</xsl:stylesheet>
XML Output
Now an xmlns
attribute is only present on the McsDkSMBMsg
element.
<?xml version="1.0" encoding="UTF-8"?>
<McsDkSMBMsg xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/McsDkSMBMsg">
<Creation>Testing</Creation>
</McsDkSMBMsg>
That said, perhaps your code could need some improvement. You are applying a for-each
to the outermost element - of which there can only be one - which makes no sense. Also, it might be more reasonable to define a prefix for the new namespace. And you are calling a named template for no obvious reason.
The usefulness of it depends on the actual XML input and on other code you already have.
Improved Stylesheet
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="un:unece:260:data:EEM-DK_RequestChangeOfSupplier:v2"
xmlns:msg="http://schemas.microsoft.com/dynamics/2008/01/documents/McsDkSMBMsg"
exclude-result-prefixes="ns1">
<xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="yes" omit-xml-declaration="no"/>
<xsl:template match="ns1:DK_RequestChangeOfSupplier">
<msg:McsDkSMBMsg>
<xsl:element name="msg:Creation">Testing</xsl:element>
</msg:McsDkSMBMsg>
</xsl:template>
</xsl:stylesheet>