This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: cumulative sum along linked list


Hi Steve,

> I need some type of recursive template that will run throught each
> <item> and form a cumulative sum on <data> tracing back through to
> other <item>'s following the <dependson> tag. I need output that
> looks something like this (not the stuff in parentheses

First, since you have links between the item elements, I would set up
a key that enabled you to quickly jump from an item to the item that
it depends on. You need to match the item elements and use their id
attributes in the key, as follows:

<xsl:key name="items" match="item" use="@id" />

Now, if you're on an item, you can find the item that it depends on by
accessing the 'items' key with the value of the dependson child
element:

  key('items', dependson)

As you said, you need a recursive template that returns the sum of
this item and all the items that it depends on. I'd use a
tail-recursive matching template, in 'sum' mode, with a $sum parameter
to keep track of the current sum, passed in by previous items.

If the item depends on another item, then you can find the sum by
applying templates to the item it depends on, passing a new value for
the $sum parameter (the passed $sum + the data of the current item).
If there's no dependency, then the sum is the passed $sum + the data
of the current item.

<xsl:template match="item" mode="sum">
  <xsl:param name="sum" select="0" />
  <xsl:variable name="dependson" select="key('items', dependson)" />
  <xsl:choose>
    <xsl:when test="$dependson">
      <xsl:apply-templates select="$dependson" mode="sum">
        <xsl:with-param name="sum" select="$sum + data" />
      </xsl:apply-templates>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$sum + data" />
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

To make your table, and display the results, you need a template that
applies templates to the item in sum mode, which looks something like:

<xsl:template match="items">
  <table>
    <tr><th>Item</th><th>Sum</th></tr>
    <xsl:for-each select="item">
      <tr>
        <td><xsl:value-of select="@id" /></td>
        <td><xsl:apply-templates select="." mode="sum" /></td>
      </tr>
    </xsl:for-each>
  </table>
</xsl:template>

I wasn't sure if the final column was just to illustrate what was
going on or if you were interested in outputting it as well. If you do
want to add the equation to the table, then you can use the same kind
of recursion to step through the items, this time keeping track of the
string (or just outputting the string bit by bit, depending on how you
want to do it).

I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]