Jagan
Jagan

Reputation: 3

Append new xml node under existing xml nodes using xslt

I am trying to append a new XML node under existing XML node but i wasn't able to achieve the desired result.

Please find my below XML,

    <Root>
        <Row>
            <A1>0</A1>
            <A2>1</A2>
            <Preferred_First_Name>aaaa</Preferred_First_Name>
            <Preferred_Last_Name>yyyy</Preferred_Last_Name>
            <location>xxxx</location>
            <ID>12345</ID>
        </Row>
    </Root>

I want to modify the above XML in such a way that Preferred_First_Name, Preferred_Last_Name and location node need to be under a new XML tag "Data".

The desired output should be like below,

<Root>
    <Row>
        <A1>0</A1>
        <A2>1</A2>
        <Data>
            <Preferred_First_Name>aaaa</Preferred_First_Name>
            <Preferred_Last_Name>yyyy</Preferred_Last_Name>
            <location Descriptor="xxxx">
                <ID type="ID">xxxx</ID>
                <ID type="LocationID">xxxx</ID>
            </location>
        </Data>
        <ID>12345</ID>
    </Row>
</Root>

Can someone please help?

Upvotes: 0

Views: 1708

Answers (2)

Vebbie
Vebbie

Reputation: 1695

If it is okay to put <ID> after <Data> mentioned by Tim C, then the optimized solution can be:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="xml" 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="Row">
    <Row>
        <xsl:apply-templates select="child::node()[not(self::Preferred_First_Name or self::Preferred_Last_Name
                                                    or self::location)]" />
        <Data>
             <xsl:apply-templates select="child::node()[self::Preferred_First_Name or self::Preferred_Last_Name
                                                    or self::location]"/>  
        </Data>
    </Row>
</xsl:template>

</xsl:stylesheet>

Upvotes: 0

Nikhil Karande
Nikhil Karande

Reputation: 56

you can use below

<?xml version="1.0" encoding="utf-16"?>
<xsl:stylesheet xmlns:xalan="http://xml.apache.org/xalan" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" version="1.0">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
    <xsl:template match="Root">
        <xsl:element name="Root">
            <xsl:call-template name="Row" />
        </xsl:element>
    </xsl:template>
    <xsl:template name="Row">
        <xsl:element name="Row">
            <xsl:copy-of select="Row/A1"/>
            <xsl:copy-of select="Row/A2"/>
            <xsl:element name="Data">
            <xsl:copy-of select="Row/Preferred_First_Name"/>
            <xsl:copy-of select="Row/Preferred_Last_Name"/>
            <xsl:element name="location">
                <xsl:attribute name="Descriptor">
                    <xsl:value-of select="Row/location"/>
                </xsl:attribute>
                <xsl:element name="ID">
                    <xsl:attribute name="type">
                        <xsl:value-of select="'ID'"/>
                    </xsl:attribute>
                    <xsl:value-of select="Row/location"/>
                </xsl:element>
            <xsl:element name="ID">
                <xsl:attribute name="type">
                    <xsl:value-of select="'LocationID'"/>
                </xsl:attribute>
                <xsl:value-of select="Row/location"/>
            </xsl:element>
            </xsl:element>
                    <xsl:copy-of select="Row/ID"/>
        </xsl:element>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Please let me know this helps you

Upvotes: 0

Related Questions