Home > database >  XSL rename tag name if condition is met
XSL rename tag name if condition is met

Time:06-11

I have below XML that I need to transform:

XML

<CONTENT>
    <DESCRIPTION TYPE="NODE"></DESCRIPTION>
    <DETAIL TYPE="NODE"></DETAIL>
    <DATA TYPE="NODE">
        <ITEM DESC="ENTITY" VALUE="Y"></ITEM>
        <ITEM DESC="REQUEST" VALUE="Y"></ITEM>
    </DATA> 
</CONTENT>

The criteria is for every element having TYPE="NODE" rename the tag name by NODE and have as DESC the previous tag name, this also applies for the root element CONTENT as shown below:

Expected XML

<NODE DESC="CONTENT">
    <NODE DESC="DESCRIPTION"></NODE>
    <NODE DESC="DETAIL"></NODE>
    <NODE DESC="DATA">
        <ITEM DESC="ENTITY" VALUE="Y"></ITEM>
        <ITEM DESC="REQUEST" VALUE="Y"></ITEM>
    </NODE>
</NODE>

I was able to rename root tag using below transformation, but no idea on how to do the rest, I was trying with <xsl:if test="DESC = 'NODE'"> but got stuck:

XSL

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template> 

    <xsl:template match="CONTENT">
        <NODE DESC="CONTENT">
            <xsl:apply-templates select="@*|node()" />          
        </NODE>
    </xsl:template>

</xsl:stylesheet>

CodePudding user response:

Change your stylesheet to

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" omit-xml-declaration="yes" />

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template> 

    <xsl:template match="CONTENT|*[@TYPE='NODE']">
        <NODE DESC="{name()}">
            <xsl:apply-templates select="@*[not(name()='TYPE')]|node()" />          
        </NODE>
    </xsl:template>

</xsl:stylesheet>

The output should be as expected. If you use namespaces, you should probably change the name()s to local-name().

  • Related