codiacTushki
codiacTushki

Reputation: 750

XSLT to add new tag and copy some of the existing elements under it

I want to add new tag in the xml and copy some elements from the existing XML as a child elements for this newly added Tag.
My existing XML file is:

<App>
<TITLE>Application NAME</TITLE>
<USER>USER NAME</USER>
<COL>
    <TEXT>Sr No.</TEXT>
    <INDEX>1</INDEX>
</COL>
<COL>
    <TEXT>Name</TEXT>
    <INDEX>1</INDEX>
</COL>
<COL>
    <TEXT>SubName</TEXT>
    <INDEX>1</INDEX>
</COL>
<FILTER>
    <LABEL>NAME</LABEL>
    <NAME>FilterByName</NAME>
</FILTER>
<FILTER>
    <LABEL>SUBNAME</LABEL>
    <NAME>FilterBySubName</NAME>
</FILTER>
</App>

and I want to add new Tag COL_LIST and move all COL elements inside it. So, my desired output XML would be

<App>
<TITLE>Application NAME</TITLE>
<USER>USER NAME</USER>
<COL_LIST>
    <COL>
        <TEXT>Sr No.</TEXT>
        <INDEX>1</INDEX>
    </COL>
    <COL>
        <TEXT>Name</TEXT>
        <INDEX>1</INDEX>
    </COL>
    <COL>
        <TEXT>SubName</TEXT>
        <INDEX>1</INDEX>
    </COL>
</COL_LIST>
<FILTER>
    <LABEL>NAME</LABEL>
    <NAME>FilterByName</NAME>
</FILTER>
<FILTER>
    <LABEL>SUBNAME</LABEL>
    <NAME>FilterBySubName</NAME>
</FILTER>
</App>

I tried this transformation using following XSLT file

<?xml version="1.0" encoding="UTF-8"?>
<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:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>
<xsl:template match="App">
    <xsl:copy>
        <COL_LIST>
            <xsl:apply-templates select="@*|COL"/>
        </COL_LIST>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>

But, i am loosing other tags except COL from the existing XML and i am getting the resultant XML as

<App>
<TITLE>Application NAME</TITLE>
<USER>USER NAME</USER>
<COL_LIST>
    <COL>
        <TEXT>Sr No.</TEXT>
        <INDEX>1</INDEX>
    </COL>
    <COL>
        <TEXT>Name</TEXT>
        <INDEX>1</INDEX>
    </COL>
    <COL>
        <TEXT>SubName</TEXT>
        <INDEX>1</INDEX>
    </COL>
</COL_LIST>
</App>

Upvotes: 2

Views: 2267

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 116992

try it this way:

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="App">
    <xsl:copy>
        <xsl:apply-templates select="TITLE|USER"/>
        <COL_LIST>
            <xsl:apply-templates select="COL"/>
        </COL_LIST>
        <xsl:apply-templates select="FILTER"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

If the order is not important, you could simplify it to:

<xsl:template match="App">
    <xsl:copy>
        <xsl:apply-templates select="*[not(self::COL)]"/>
        <COL_LIST>
            <xsl:apply-templates select="COL"/>
        </COL_LIST>
    </xsl:copy>
</xsl:template>

Upvotes: 3

Related Questions