• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Ron McLeod
  • paul wheaton
  • Jeanne Boyarsky
Sheriffs:
  • Paul Clapham
  • Devaka Cooray
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
  • Himai Minh
Bartenders:

xslt for-each, get previous tag value

 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello!

I�m using xslt to create a text document with data from a xml-structure.

I�m using xsl:for-each to loop throw the xml. But I have problem to know is the previous tag have the same value as the current tag. Trying to solve this with recursive calls but it fails. The recursive call seems not to be called because it is inside a for-each loop.
My thought with the recursive call was that the current value should be compared with the next tags value.

The purpose of everything is that I will only write the header if the tag LAN has a new value.


xslt:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:java="http://xml.apache.org/xslt/java"
xmlns:text="http://www.ora.com/XSLTCookBook/namespaces/text"/>
<xsl utput method="text"/>


<xsl:template name="root" match="/">
<xsl:call-template name="main">
<xsl:with-param name="lan" select="'0'"/>
</xsl:call-template>
</xsl:template>

<xsl:template name="main">
<xsl aram name="lan"/>
<xsl:for-each select="ROWSET/ROW">
<!--This if-statement is not working because the lan parameter is always 0. (never changing value) -->
<xsl:if test="number(LAN) != number($lan)">
<xsl:call-template name="performLanHeader">
<xsl:with-param name="lan" select="LAN"/>
</xsl:call-template>
</xsl:if>

<xsl:call-template name="performrow">
</xsl:call-template>

<!--recursive call to template main, is never called, WHY?? -->
<xsl:call-template name="main">
<xsl:with-param name="lan" select="LAN"/>
</xsl:call-template>

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

<xsl:template name="performLanHeader">
<xsl aram name="lan"/>
Department: <xsl:value-of select="$lan"/>

<xsl:text>
</xsl:text>
</xsl:template>

<xsl:template name="performrow">
<xsl:value-of select="RUBRIK1"/>
<xsl:value-of select="K1"/>
<xsl:value-of select="K2"/>
<xsl:value-of select="K3"/>
<xsl:value-of select="K4"/>
<xsl:text>
</xsl:text>
</xsl:template>

</xsl:stylesheet>


Xml:
<?xml version="1.0" encoding="UTF-8"?>
<ROWSET>
<ROW num="1">
<LAN>01</LAN>
<RUBRIK1>OPPENVARD</RUBRIK1>
<RUBRIK2>EGENVARD</RUBRIK2>
<K1>123456789</K1>
<K2>0</K2>
<K3>898.5</K3>
<K4>9</K4>
</ROW>

<ROW num="2">
<LAN>01</LAN>
<RUBRIK1>OPPENVARD</RUBRIK1>
<RUBRIK2>HJALPMEDEL</RUBRIK2>
<K1>1893.5</K1>
<K2>5</K2>
<K3>2901</K3>
<K4>6</K4>
</ROW>
<ROW num="3">
<LAN>05</LAN>
<RUBRIK1>OPPENVARD</RUBRIK1>
<RUBRIK2>HJALPMEDEL</RUBRIK2>
<K1>1893.5</K1>
<K2>5</K2>
<K3>1893.5</K3>
<K4>5</K4>
</ROW>
<ROW num="4">
<LAN>06</LAN>
<RUBRIK1>OPPENVARD</RUBRIK1>
<RUBRIK2>KREDITERING</RUBRIK2>
<K1>0</K1>
<K2>0</K2>
<K3>360</K3>
<K4>3</K4>
</ROW>
</ROWSET>

This is my wished print result:

Department: 01
OPPENVARD 123456789 0 898.5 9
OPPENVARD 1893.5 5 2901 6

Department: 05
OPPENVARD 1893.5 5 1893.5 5

Department: 06
OPPENVARD 0 0 360 3


Thanks for any help.

Regards
Mats
 
Ranch Hand
Posts: 429
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, the recursion won't work from the for-each loop because your context node inside the loop is ROW, so you're calling the main template on ROW.

I'm not sure if this will work, but you could try the following:

<xsl:template name="main">
<xsl:for-each select="ROWSET/ROW">
<xsl:variable name="pos" select="position()"/>
<xsl:if test="number(LAN) != number(../ROW[$pos - 1]/LAN)">
<xsl:call-template name="performLanHeader"/>
</xsl:if>
<xsl:call-template name="performrow"/>
</xsl:for-each>
</xsl:template>

I've actually had some problems with position() not returning exactly what I'd expect, so this may only work after some tinkering. Also I'm not sure what will happen with the first row when it checks against number(../../ROWSET/ROW[0]/LAN).

-Yuriy
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic