Reputation: 95
Working on the xsl and i am looking for variable inside a loop to reset on new record.
Fetching records from oracle table
<xsl:variable name="curr_temp_emp_no" select="'##'"/>
<xsl:for-each select="/data/test/loof/super_incompleted">
<xsl:variable name="curr_temp_emp_no2" select="emp_no"/>
<xsl:choose>
<xsl:when test="$curr_temp_emp_no2 != $curr_temp_emp_no">
<xsl:value-of select="emp_no"/><fo:inline> - </fo:inline><xsl:value-of select="variable_desc"/></xsl:when>
<xsl:otherwise>
<xsl:value-of select="variable_desc"/>
</xsl:otherwise>
</xsl:choose>
<xsl:variable name="curr_temp_emp_no" select="emp_no"/>
</xsl:for-each>
I am trying to compare variable "curr_temp_emp_no" if new value only it prints "emp_no - variable_desc" otherwise(if same emp_no) then print only "variable_desc".
I understood from google that Variables in XSLT are immutable, once we assign them a value, we can't change them.
Refence: Can you simulate a boolean flag in XSLT?
Can anyone please help me over here in writting this logic.
Upvotes: 0
Views: 740
Reputation: 95
Thanks for your reply. I have used the "preceding-sibling::" which solved my problem. Now the code is something like this.
<xsl:for-each select="/data/test/loof/super_incompleted">
<xsl:variable name="curr_temp_emp_no2" select="emp_no"/>
<xsl:choose>
<xsl:when test="$curr_temp_emp_no2 != preceding-sibling::super_incompleted[1]/emp_no">
<xsl:value-of select="emp_no"/><fo:inline> - </fo:inline><xsl:value-of select="variable_desc"/></xsl:when>
<xsl:otherwise>
<xsl:value-of select="variable_desc"/>
</xsl:otherwise>
</xsl:choose>
<xsl:variable name="curr_temp_emp_no" select="emp_no"/>
</xsl:for-each>
Earlier the table was like this. 1- ABC,1- DFE,1- GFH 2- DFG,2- FGH,2- SDS,2- RTY
Now table looks like this. 1- ABC,DFE,GFH 2- DFG,FGH,SDS
Upvotes: 0
Reputation: 163322
You're asking us to reverse engineer your requirements from non-working code, which is always a challenge, but you seem to be carrying over ideas from procedural programming languages which gives us some clues as to what you imagine you want this code to do.
Basically it looks like a "group-adjacent" problem. In XSLT 2.0 you would do
<xsl:for-each-group select="/data/test/loof/super_incompleted"
group-adjacent="emp_no">
...
</xsl:for-each-group>
If you're stuck with XSLT 1.0 then the usual approach is to process the sequence of nodes with a recursive named template rather than a for-each instruction: you pass the list of nodes as a parameter to the template, together with the current employee id, and then in the template you process the first node in the list, and call yourself recursively to process the remainder of the list.
@ChristianMosz has expanded this suggestion into working code.
Upvotes: 1
Reputation: 543
It looks like you want to compare the last two values. I could achieve this by:
<xsl:template match="/">
<xsl:call-template name="helperTemplate">
<xsl:with-param name="nodes" select="/data/test/loof/super_incompleted"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="helperTemplate">
<xsl:param name="nodes"/>
<xsl:param name="oldVal" select="''"/>
<xsl:if test="$nodes">
<xsl:variable name="curr_temp_emp_no" select="$nodes[1]/emp_no"/>
<xsl:choose>
<xsl:when test="$curr_temp_emp_no != $oldVal">
<xsl:value-of select="$curr_temp_emp_no"/>
<fo:inline> - </fo:inline>
<xsl:value-of select="$nodes[1]/variable_desc"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$nodes[1]/variable_desc"/>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="helperTemplate">
<xsl:with-param name="nodes" select="$nodes[position() > 1]"/>
<xsl:with-param name="oldVal" select="$nodes[1]/emp_no"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
If you want to have the comparison on all values(if there was no previous element with that content), you can sort them first and use the same code.
Upvotes: 1