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]
Other format: [Raw text]

Re: how to apply sum to a comma delimited list


Florin Dragu wrote:
> is there any way that I can use sum() functions in XSLT on a comma separated
> list (received as an output from a template)?

It would be easiest if when you built the comma-separated list, you created a
result tree fragment in which each value you want in the total is in a
separate element. The string-value of the fragment can still give you the list
output that you want, but you can also use XPath/XSLT's sum function on the
node-set equivalent of the fragment. xalan:nodeSet() (or exsl:node-set() if
you're using a more recent snapshot of Xalan) will convert the RTF to a
node-set.

The most portable alternative is to use a recursive template to dissect the
string.

Given XML:

<?xml version="1.0"?>
<some>
  <data>1</data>
  <data>2</data>
  <data>3</data>
  <data>5</data>
  <data>7</data>
  <data>11</data>
</some>

Here's a stylesheet that demonstrates both solutions:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                xmlns:exsl="http://exslt.org/common";
                xmlns:xalan="http://xml.apache.org/xalan";
                exclude-result-prefixes="xalan exsl">
      
<xsl:output method="text"/>

<xsl:template match="/">
  <xsl:variable name="list">
    <xsl:for-each select="some/data">
      <dummyElement>
        <xsl:value-of select="."/>
      </dummyElement>
      <xsl:if test="position() != last()">
        <comma>,</comma>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>
  <xsl:text>The list is: </xsl:text>
  <xsl:value-of select="$list"/>
  <xsl:text>&#10;The sum is: </xsl:text>
  <xsl:choose>
    <xsl:when test="function-available('exsl:node-set')">
      <xsl:value-of select="count(exsl:node-set($list)/dummyElement)"/>
    </xsl:when>
    <xsl:when test="function-available('xalan:nodeSet')">
      <xsl:value-of select="sum(xalan:nodeSet($list)/dummyElement)"/> 
    </xsl:when>
    <xsl:otherwise>
      <xsl:call-template name="sum">
        <xsl:with-param name="str" select="string($list)"/>
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template name="sum">
  <xsl:param name="str"/>
  <xsl:param name="total" select="0"/>
  <xsl:choose>
    <xsl:when test="contains($str,',')">
      <xsl:call-template name="sum">
        <xsl:with-param name="str" select="substring-after($str,',')"/>
        <xsl:with-param name="total" select="$total + substring-before($str,',')"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$total + $str"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>

   - Mike
____________________________________________________________________________
  mike j. brown                   |  xml/xslt: http://skew.org/xml/
  denver/boulder, colorado, usa   |  resume: http://skew.org/~mike/resume/

 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]