sanjay
sanjay

Reputation: 1020

XSLT - Change the order of nodes

I have a xml linke this,

<person-group>
    <name>
        <surname>Agate</surname>
        <given-names>R. J.</given-names>
    </name>
    <name>
        <surname>Choe</surname>
        <given-names>M.</given-names>
    </name>
    <name>
        <surname>Arnold</surname>
        <given-names>A. P.</given-names>
    </name>
</person-group>

in the output xml, I have to change the order of <surname> and <given-names> as <given-names> and <surname> expect first node . so the output xml should look like,

<person-group>
    <name>
        <surname>Agate</surname>
        <given-names>R. J.</given-names>
    </name>
    <name>
        <given-names>M.</given-names>
        <surname>Choe</surname>   
    </name>
    <name>    
        <given-names>A. P.</given-names>
        <surname>Arnold</surname>
    </name>
</person-group>

I wrote following xsl to do this task,

<xsl:template match="person-group">
        <person-group>
            <xsl:apply-templates/>
        </person-group>
    </xsl:template>

    <xsl:template match="name[position()=1]">
        <name>
            <xsl:apply-templates select="child::surname" />
            <xsl:apply-templates select="child::given-names" />
        </name>
    </xsl:template>

    <xsl:template match="name[position()>1]">
        <name>
            <xsl:apply-templates select="child::given-names"/>
            <xsl:apply-templates select="child::surname"/>
            <xsl:apply-templates/>
        </name>
    </xsl:template>

    <xsl:template match="surname" >
        <surname>
            <xsl:apply-templates />
        </surname>
    </xsl:template>

    <xsl:template match="given-names" >
        <given-names>
            <xsl:apply-templates />
        </given-names>
    </xsl:template>

But this, doubled the content of <name> nodes and gave me a output like this,

<person-group>
    <name>
        <surname>Agate</surname>
        <given-names>R. J.</given-names>
    </name>
    <name>
        <given-names>M.</given-names>
        <surname>Choe</surname>
        <given-names>M.</given-names>
        <surname>Choe</surname>
    </name>
    <name>
        <given-names>A. P.</given-names>
        <surname>Arnold</surname>
        <given-names>A. P.</given-names>
        <surname>Arnold</surname>
    </name>
</person-group>

How can I modify my code to get the expected result..

Upvotes: 1

Views: 1066

Answers (1)

Joel M. Lamsen
Joel M. Lamsen

Reputation: 7173

you just need an identity template and the template override for name nodes whose position is greater than 1.

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

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>    

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

    <xsl:template match="name[position() &gt; 1]">
        <xsl:copy>
            <xsl:apply-templates select="given-names,surname"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

Upvotes: 4

Related Questions