[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

RE: XSL problem using sum() function

Subject: RE: XSL problem using sum() function
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Thu, 18 Nov 2004 18:12:01 -0000
xsl variable sum
(Dave P: could we have this in the FAQ please?)

The general problem of summing over a computed value has three noteworthy
solutions. Let's use f($x) for the function that computes the number you
want to total, given a node $x (the canonical example is summing price times
quantity, where f() is $x/@price * $x/@qty), and let's use $seq for the
sequence of nodes that you want to sum over. That is, you want to apply f()
to each node in $seq and return the sum of the results.

(a) In XPath 2.0

sum(for $i in $seq return f($i))

In fact, in the Oct 2004 draft it's even simpler, but this won't be
available until Saxon 8.2:

sum($seq/f(.))

Concrete examples:

sum(//item/(@price * @qty))

sum(//item/number(translate(., '$', '')))

(b) In XSLT 1.0 with xx:node-set() extension

Create a result-tree-fragment containing the computed numeric values as
values of element or attribute nodes; use xx:node-set() to convert this RTF
to a node-set, and then use sum() over the nodes.  For example:

<xsl:variable name="temp">
  <xsl:for-each select="$seq">
    <item value="{f(.)}"/>
  </xsl:for-each>
</xsl:variable>

or more concretly,

<xsl:variable name="temp">
  <xsl:for-each select="//item">
    <item value="{@price * @qty}"/>
  </xsl:for-each>
</xsl:variable>

<xsl:value-of select="sum(xx:node-set($temp)/item/@value)"/>

(c) In pure XSLT 1.0

Recurse over the input sequence using a recursive named template:

<xsl:template name="total">
  <xsl:param name="seq"/>
  <xsl:param name="total-so-far" select="0"/>
  <xsl:choose>
    <xsl:when test="$seq">
        <xsl:call-template name="total">
          <xsl:with-param name="seq" 
                          select="$seq[position()!=1]"/>
          <xsl:with-param name="total-so-far" 
                          select="$total-so-far + f($seq[1])"/>
        </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="$total-so-far"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

Michael Kay
http://www.saxonica.com/


> -----Original Message-----
> From: Christopher Hansen [mailto:chansen1@xxxxxxxxx] 
> Sent: 18 November 2004 17:29
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject:  XSL problem using sum() function
> 
> Im trying to get the sum of all salaries for company:BG (see XML
> below).  Im using translate to remove the '$' and ',' from the dollar
> amounts and then, trying to sum them up.  But i get the error that it
> cannot convert String to NodeList.  I've tried some other workarounds
> but i just cant seem to get it.   Any ideas?
> Thanks
> Chris
> 
> 
> The XSL:
> 
> <?xml version="1.0"?>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> version="1.0">
> 
>         <xsl:output method="html"/>
> 
>         <xsl:variable name="workssection" 
> select="document('works.xml')" />
>         <xsl:variable name="empsection" 
> select="document('employees.xml')" />
> 
>         <xsl:template match="/">
>         <xsl:for-each select="$workssection//works-for/" >
>           <xsl:if test ="company-name = 'BG'" >
>             <xsl:variable name="trans" 
> select="translate(salary,'$,','')" />
>             <p><xsl:value-of select="sum($trans)" /></p>
>           </xsl:if>
>         </xsl:for-each>
> 
>         </xsl:template>
> </xsl:stylesheet>
> 
> 
> 
> A portion of the XML file:
> <works>
>       <works-for>
>             <emp-name>John Doe</emp-name>
>             <company-name>BG</company-name>
>             <company-city>Ames</company-city>
>             <salary>$70,000</salary>
>       </works-for>
> 
>       <works-for>
>             <emp-name>Margaret Thatcher</emp-name>
>             <company-name>BG</company-name>
>             <company-city>London</company-city>
>             <salary>$7,000,000</salary>
>       </works-for>
>       ....

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.