Re: [xsl] Sum Problem

Subject: Re: [xsl] Sum Problem
From: Joerg Heinicke <joerg.heinicke@xxxxxx>
Date: Sat, 01 Jun 2002 02:30:37 +0200
Hello Kieran,

in general in XSLT you can not "pass parameters back", you only can
store the "result of a template" in a variable:

<xsl:variable name="sum">
<xsl:apply-templates select="sections/section[@id=$A]/item[@id=$index]">
     <xsl:with-param name="index" select="$index"/>
     <xsl:with-param name="total" select="$total"/>
</xsl:apply-templates>
</xsl:variable>

But this doesn't solve your recursive problem.

Here is my stylesheet:

<xsl:param name="total" select="0"/>
<xsl:param name="index" select="1"/>
<xsl:param name="section-string" select="'AB'"/>

<xsl:key name="items" match="item" use="concat(../@id,'::',@id)"/>

<xsl:template match="sections">
  <table border="1">
    <tr>
      <td>&#160;</td>
      <td>index</td>
      <td>total</td>
    </tr>
    <tr>
      <td>starting</td>
      <td><xsl:value-of select="$index"/></td>
      <td><xsl:value-of select="$total"/></td>
    </tr>
    <xsl:apply-templates select="key('items', concat('A::',$index))">
      <xsl:with-param name="total" select="$total"/>
      <xsl:with-param name="index" select="$index"/>
    </xsl:apply-templates>
  </table>
</xsl:template>

<xsl:template match="item">
<xsl:param name="total" select="0"/>
<xsl:param name="index" select="0"/>
<xsl:variable name="newtotal" select="$total + @value"/>
<xsl:variable name="newindex" select="$index + @value"/>
<tr>
<td><xsl:value-of select="../@id"/></td>
<td><xsl:value-of select="$newindex"/></td>
<td><xsl:value-of select="$newtotal"/></td>
</tr>
<!-- switches from A to B and the other way around -->
<xsl:variable name="section" select="substring($section-string, string-length(substring-after($section-string, ../@id)) + 1, 1)"/>
<xsl:if test="not(key('items', concat($section, '::', $newindex)))">
<tr>
<td colspan="3">
No item with index <xsl:value-of select="$newindex"/>
in Section <xsl:value-of select="$section"/>.
</td>
</tr>
</xsl:if>
<xsl:apply-templates select="key('items', concat($section, '::', $newindex))">
<xsl:with-param name="total" select="$newtotal"/>
<xsl:with-param name="index" select="$newindex"/>
</xsl:apply-templates>
</xsl:template>


What's this for an algorithm? And what's the sense of calculating $index and $total? When you now the difference 1 at the start, then the difference must be 1 at the end too, because to both sums always @value will be added. So you only need to calculate $index and remove or add the difference from the start for getting $total.

Regards,

Joerg


Kirwan, K. wrote:
> Dear All,
>
> I've an XML file as follows-
>
>
> <section id="A">
> <item id="1" value="1"/>
> <item id="2" value="2"/>
> <item id="3" value="2"/>
> <item id="4" value="2"/>
> </section>
> <section id="B">
> <item id="1" value="1"/>
> <item id="2" value="10"/>
> <item id="3" value="3"/>
> <item id="4" value="4"/>
> </section>
>
> I would like to sum CERTAIN values within the above xml as follows:
>
> 1- starting conditions $index=1 $total=0
> 2- select sectionA/item[@index=$index] (has @value=1)
> 3- calculate $total=$total+@value (=0+1)
> 4- calculate $index=$index+@value (=1+1)
>
> 5- select sectionB/item[@index=$index] (item2 which has
> value=10)
> 6- repeat steps 3-4 using new $index -> $total=1+10,
> index=2+10
>
> I'm guessing this requires some form of recursion but can't figure out how
> to pass
> extracted parameters back to the calling template.
> i.e. i'd like to do something like this with the updated totals returned to
> the calling root-template.
> ---------------------
> <?xml version="1.0"?>
> <xsl:transform
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
> version="1.0">
> <xsl:output method="xml"/>
>
> <xsl:param name="A" select="'A'"/>
> <xsl:param name="B" select="'B'"/>
> <xsl:param name="index" select="1"/>
> <xsl:param name="total" select="0"/>
>
> <xsl:template match="/">
> <sections>
> <section1>
> <xsl:apply-templates select="sections/section[@id=$A]/item[@id=$index]">
> <xsl:with-param name="index" select="$index"/>
> <xsl:with-param name="total" select="$total"/>
> </xsl:apply-templates>
> </section1>
> <section2>
> <xsl:apply-templates select="sections/section[@id=$A]/item[@id=$index]">
> <xsl:with-param name="index" select="$index"/>
> <xsl:with-param name="total" select="$total"/>
> </xsl:apply-templates>
> </section2>
> </sections>
> </xsl:template>
>
> <xsl:template match="item">
> <xsl:param name="index">
> <xsl:param name="total">
> <xsl:param name="total"><xsl:value-of select="$total+@value"/></xsl:param>
> <xsl:value-of select="$total+@value"/>
> </xsl:template>
>
> </xsl:transform>
>
> Kieran Kirwan



XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



Current Thread