Search code examples
xmlxsltpositioning

XSLT Adding node in the correct place


I have the following XML structure:

<Main>
    <Node1>Definite</Node1>
    <Node2>Definite</Node2>
    <Node3>Definite</Node3>
    <Node4>Definite</Node4>
    <Node5>Definite</Node5>
    <Node6>Definite</Node6>
    <A>Possible</A>
    <B>Possible</B>
    <C>Possible</C>
    <D>Possible</D>    
    <E>Possible</E>
    <F>Possible</F>
    <G>Possible</G>
    <H>Possible</H>
    <I>Possible</I>
</Main>

The nodes named individual letters eg.<A> are nodes that may not exist within the XML structure while all other nodes are definite.

I need to insert the node <ZZZ> within the structure so that it always sits in the position shown below.

<Main>
    <Node1>Value</Node1>
    <Node2>Value</Node2>
    <Node3>Value</Node3>
    <Node4>Value</Node4>
    <Node5>Value</Node5>
    <Node6>Value</Node6>
    <A>Value</A>
    <B>Value</B>
    <C>Value</C>
    <D>Value</D>    
    <E>Value</E>
    <ZZZ>Value</ZZZ>
    <F>Value</F>
    <G>Value</G>
    <H>Value</H>
    <I>Value</I>
</Main>

So say node <E> and <C> and <H> didnt exist it would be:

<Main>
    <Node1>Value</Node1>
    <Node2>Value</Node2>
    <Node3>Value</Node3>
    <Node4>Value</Node4>
    <Node5>Value</Node5>
    <Node6>Value</Node6>
    <A>Value</A>
    <B>Value</B>
    <D>Value</D>    
    <ZZZ>Value</ZZZ>
    <F>Value</F>
    <G>Value</G>
    <I>Value</I>
</Main>

Hope this is explained clear enough :)


Solution

  • well it is depending on which elements are requiered and which are optional! E.g. if you can say <F> is requierd you can insert the ZZZ-Element before the F-Element:

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

    if you can not say, there is a requiered element, you need to insert in a template for the Main-Element:

    <xsl:template match="Main">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="Node1|Node2|Node3|Node4|Node5|Node6|A|B|C|D|E"/>
            <ZZZ>Value</ZZZ>
            <xsl:apply-templates select="F|G|H|I"/>
        </xsl:copy>
    </xsl:template>