user2202930
user2202930

Reputation: 11

How to compare previous node element value with current node element value in foreach in xslt

How we can compare Previous Item1 value with the current item1 value with in for each loop in xslt.can you please advise me.below is the input.

input:

<t>
<Items>
<Item1>24</Item1>

</Items>

<Items>
<Item1>25</Item1>

</Items>

<Items>
<Item1>25</Item1>

</Items>

</t>

output:

<t>

<xsl:for-each select="Items">

 <xsl:if previos Item1 != current Item1><!-- compare previous item1 with current Item1 -->





 </xsl:for-each>
 </t>

Upvotes: 1

Views: 7591

Answers (3)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243459

Here is a general solution for the general case when the items in the node-list aren't siblings (and may even belong to different documents):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
     <xsl:apply-templates select="Items/Item1">
      <xsl:with-param name="pNodeList" select="Items/Item1"/>
     </xsl:apply-templates>
 </xsl:template>

 <xsl:template match="Item1">
   <xsl:param name="pNodeList"/>

   <xsl:variable name="vPos" select="position()"/>
   <xsl:copy-of select="self::node()[not(. = $pNodeList[$vPos -1])]"/>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

<t>
    <Items>
        <Item1>24</Item1>
    </Items>
    <Items>
        <Item1>25</Item1>
    </Items>
    <Items>
        <Item1>25</Item1>
    </Items>
</t>

the wanted, (assumed) correct result is produced:

<Item1>24</Item1>
<Item1>25</Item1>

Upvotes: 3

Ian Roberts
Ian Roberts

Reputation: 122364

Don't try and think about this in terms of "iterations", instead think about how to select the correct nodes for the for-each in the first place. It looks like you want to process only Items elements whose Item1 is not the same as its immediately preceding sibling in the input tree

<xsl:for-each select="Items[preceding-sibling::Items[1]/Item1 != Item1]">

If you want to make much progress with XSLT you need to stop thinking about procedural things like loops and assignments and instead learn to think functionally - how does the output I want relate to the input I'm starting from.

Upvotes: 1

Jukka Matilainen
Jukka Matilainen

Reputation: 10188

You can use the preceding-sibling axis, for example like this:

not(preceding-sibling::Items[1]/Item1 = Item1)

Upvotes: 1

Related Questions