Home > Software engineering >  XSL variable tag name if condition is met
XSL variable tag name if condition is met

Time:06-15

I have below XML that I need to transform:

XML

<CONTENT>
    <DATA TYPE="NODE">
        <ITEM DESC="ENTITY" VALUE="Y"></ITEM>
        <ITEM DESC="REQUEST" VALUE="Y"></ITEM>
    </DATA>
    <ITEM TYPE="INFO"></ITEM>
    <ITEM TYPE="REQ"></ITEM>
    <TAG DESC="FLAG1"></TAG>
    <TAG DESC="FLAG2"></TAG>
    <INFO TYPE="USAGE"></INFO>
</CONTENT>

The criteria is for every element having TYPE={name} rename the tag name by {name} of the TYPE and have as DESC the previous tag name as shown below:

Expected XML

<CONTENT>
    <NODE DESC="DATA">
        <ITEM DESC="ENTITY" VALUE="Y"></ITEM>
        <ITEM DESC="REQUEST" VALUE="Y"></ITEM>
    </NODE>
    <INFO DESC="ITEM"></INFO>
    <REQ DESC="ITEM"></REQ>
    <TAG DESC="FLAG1"></TAG>
    <TAG DESC="FLAG2"></TAG>
    <USAGE DESC="INFO"></USAGE>
</CONTENT>

I have below working XSL from previous post but to make it work for this scenario I have to map for each different type, I'm trying to get a generic solution that covers everything with a TYPE={name}:

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" omit-xml-declaration="yes" />

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

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

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

    (...)

</xsl:stylesheet>

CodePudding user response:

Try:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="*[@TYPE]">
    <xsl:element name="{@TYPE}">
        <xsl:attribute name="DESC">
            <xsl:value-of select="name()" />
        </xsl:attribute>
        <xsl:apply-templates/>  
    </xsl:element>
</xsl:template>

</xsl:stylesheet>
  • Related