This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Sum Problem
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> </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