0
votes

I have a xml like following xml,

<doc>
<footnote>
    <p type="Foot">
        <link ref="http://www.facebook.com"/>
        <c>content</c>
        <d>cnotent</d>
    </p>
    <p type="Foot">
        <link ref="http://www.google.com"/>
        <c>content</c>
        <d>cnotent</d>
    </p>
</footnote>
</doc>

My requirmets are,

1) add dynamic id to <p> node which has attribute type="Foot"

2) add new node named <newNode> inside <p> node

3) add dynamic id to <newNode>

so output sholud be

<doc>
<footnote>
    <p id="ref-1" type="Foot">
        <newNode type="direct" refId="foot-1"/>
        <link ref="http://www.facebook.com"/>
        <c>content</c>
        <d>cntent</d>
    </p>
    <p id="ref-2" type="Foot">
        <newNode type="direct" refId="foot-2"/>
        <link ref="http://www.google.com"/>
        <c>content</c>
        <d>cotent</d>
    </p>
</footnote>
</doc>

I wrote following xsl to do that

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

    <!-- add new dynamic attribute to <p> -->
    <xsl:template match="p[@type='Foot']">
        <xsl:copy>
            <xsl:attribute name="id">
                <xsl:value-of select="'ref-'"/> 
                <xsl:number count="p[@type='Foot']" level="any"/>
            </xsl:attribute>

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

            <!-- add new node with dynamic attribute -->
            <newNode type="direct">
                <xsl:attribute name="refId">
                    <xsl:value-of select="'foot-'"/>
                    <xsl:number count="p[@type='Foot']" level="any"></xsl:number>
                </xsl:attribute>
            </newNode>
        </xsl:copy>

    </xsl:template>

My problem is it add new node ad last node inside <p> node (as show below) which I need to add as first node inside <p> node

      <p id="ref-1" type="Foot">
            <link ref="http://www.facebook.com"/>
            <c>content</c>
            <d>cntent</d>
            <newNode type="direct" refId="foot-1"/>
        </p>

How can I place as first node inside <p> node as shown below?

    <p id="ref-1" type="Foot">
        <newNode type="direct" refId="foot-1"/>
        <link ref="http://www.facebook.com"/>
        <c>content</c>
        <d>cntent</d>
    </p>
1

1 Answers

1
votes

You need to make sure you copy the child elements after creating the new node:

<xsl:template match="p[@type='Foot']">
    <xsl:copy>
        <xsl:attribute name="id">
            <xsl:value-of select="'ref-'"/> 
            <xsl:number count="p[@type='Foot']" level="any"/>
        </xsl:attribute>

        <xsl:apply-templates select="@*" />

        <!-- add new node with dynamic attribute -->
        <newNode type="direct">
            <xsl:attribute name="refId">
                <xsl:value-of select="'foot-'"/>
                <xsl:number count="p[@type='Foot']" level="any"></xsl:number>
            </xsl:attribute>
        </newNode>

        <xsl:apply-templates/>
    </xsl:copy>

</xsl:template>