I could not resist
so here is a solution that would be better on larger item sets
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.o
<xsl:template match="/">
<html>
<head/>
<body>
<table border="1">
<tr>
<th>ID</th>
<th>Type1</th>
<th>Type2</th>
</tr>
<xsl:for-each select="//item[1]">
<xsl:call-template name="processItem">
<xsl:with-param name="node" select="."/>
<xsl:with-param name="RT1" select="0"/>
<xsl:with-param name="RT2" select="0"/>
</xsl:call-template>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
<xsl:template name="processItem">
<xsl:param name="node"/>
<xsl:param name="RT1"/>
<xsl:param name="RT2"/>
<xsl:variable name="newRT1">
<xsl:choose>
<xsl:when test="$node/type = 1">
<xsl:value-of select="$RT1 + $node/exchange * $node/quantity"/>
</xsl:when>
<xsl:otherwise><xsl:value-
</xsl:choose>
</xsl:variable>
<xsl:variable name="newRT2">
<xsl:choose>
<xsl:when test="$node/type = 2">
<xsl:value-of select="$RT2 + $node/exchange * $node/quantity"/>
</xsl:when>
<xsl:otherwise><xsl:value-
</xsl:choose>
</xsl:variable>
<tr>
<td><xsl:value-of select="$node/id"/></td>
<xsl:choose>
<xsl:when test="$node/type = 1">
<td><xsl:value-of select="$newRT1"/></td>
<td>-</td>
</xsl:when>
<xsl:otherwise>
<td>-</td>
<td><xsl:value-of select="$newRT2"/></td>
</xsl:otherwise>
</xsl:choose>
</tr>
<xsl:if test="$node/following-sibl
<xsl:call-template name="processItem">
<xsl:with-param name="node" select="$node/following-si
<xsl:with-param name="RT1" select="$newRT1"/>
<xsl:with-param name="RT2" select="$newRT2"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
cheers
Geert
Main Topics
Browse All Topics





by: GertonePosted on 2007-06-19 at 23:38:07ID: 19322450
I would suggest that you iterate over the item elements
rg/1999/XS L/Transfor m" version="1.0"> ing::item[ type = $type]"> bling::ite m[type = $type][1]"/>
and have a recursive function work back upwards the tree to (re)calculate the running total.
This is a bit naive, but easiest to understand
If there are many items (so if the XML is rather big)
you should develop a recursive function
that loops through the item list and keeps the two running totals as seperate variables
let me know if you run into timing problems with my first solution
and I will give the second logic a shot...
or you could try that yourself based on my first solution
note that XSLT doesn't have real variables,
so you need to pass results of calulations to a recursive template instead
here is the solution
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.o
<xsl:template match="/">
<html>
<head/>
<body>
<table border="1">
<tr>
<th>ID</th>
<th>Type1</th>
<th>Type2</th>
</tr>
<xsl:for-each select="//item">
<tr>
<td><xsl:value-of select="id"/></td>
<xsl:choose>
<xsl:when test="type = 1">
<td>
<xsl:call-template name="getRT">
<xsl:with-param name="node" select="."/>
<xsl:with-param name="type" select="1"/>
<xsl:with-param name="RT" select="0"/>
</xsl:call-template>
</td>
<td>-</td>
</xsl:when>
<xsl:otherwise>
<td>-</td>
<td>
<xsl:call-template name="getRT">
<xsl:with-param name="node" select="."/>
<xsl:with-param name="type" select="2"/>
<xsl:with-param name="RT" select="0"/>
</xsl:call-template>
</td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
<xsl:template name="getRT">
<xsl:param name="node"/>
<xsl:param name="type"/>
<xsl:param name="RT"/>
<xsl:variable name="curRT" select="$RT + ($node/exchange * $node/quantity)" />
<xsl:choose>
<xsl:when test="$node/preceding-sibl
<xsl:call-template name="getRT">
<xsl:with-param name="node" select="$node/preceding-si
<xsl:with-param name="type" select="$type"/>
<xsl:with-param name="RT" select="$curRT"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$curRT"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
cheers
Geert