Ricardo Carvalho
Ricardo Carvalho

Reputation: 7

Remove prefix from element

I need to remove a prefix from an element

I have this XML

<ns:order xmlns:ns="namespace">
<row>
        <id>1</id>
    </row>
    <row>
        <id>2</id>
    </row>
</ns:order>

I have this email, but the result is not what I'm expecting, as the 2nd element also gets the prefix.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:variable name="topNode" select="name(/*)"/>
    <xsl:variable name="topNodeNamespace" select="namespace-uri(/*)"/>
    <xsl:template match="/">
        <xsl:element name="{$topNode}" namespace="{$topNodeNamespace}">
            <xsl:copy-of select="node()"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

This is what I get after running the xsl:

<?xml version="1.0" encoding="UTF-8"?>
<ns:order xmlns:ns="namespace">
    <ns:order>
        <row>
            <id>1</id>
        </row>
        <row>
            <id>2</id>
        </row>
    </ns:order>
</ns:order>

I want to get this:

<?xml version="1.0" encoding="UTF-8"?>
<ns:order xmlns:ns="namespace">
    <order>
        <row>
            <id>1</id>
        </row>
        <row>
            <id>2</id>
        </row>
    </order>
</ns:order>

Upvotes: 0

Views: 170

Answers (1)

Tim C
Tim C

Reputation: 70648

You are currently trying to add a new element as a parent of the current one. It would make more sense if you added a new child and added the existing children to that.

Try this XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:variable name="topNode" select="local-name(/*)"/>
    <xsl:template match="/*">
        <xsl:copy>
            <xsl:element name="{$topNode}">
                <xsl:copy-of select="node()"/>
            </xsl:element>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Or, without the use of a variable....

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="/*">
        <xsl:copy>
            <xsl:element name="{local-name()}">
                <xsl:copy-of select="node()"/>
            </xsl:element>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Note the use of local-name() instead of name() as local-name() will not include any prefix.

Upvotes: 1

Related Questions