简体   繁体   中英

XSL: Remove namespace prefix

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM