Assuming we want to get the sum of string-lengths of all child nodes
of the top node,
using FXSL one would write:
sum(f:map(f:string-length(), /*/node()))
Here's a complete transformation:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:f="http://fxsl.sf.net/"
exclude-result-prefixes="f xs"
<xsl:import href="../f/func-map.xsl"/>
<xsl:import href="../f/func-Operators.xsl"/>
<xsl:import href="../f/func-standardXpathFunctions.xsl"/>
<!--
This transformation must be applied to:
../data/numList.xml
Expected result: 20
-->
<xsl:strip-space elements="*"/>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:value-of select="sum(f:map(f:string-length(), /*/node()))"/>
</xsl:template>
</xsl:stylesheet>
When applied for example on this source.xml file:
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
the wanted result is produced:
20
One can use also the transform-and-sum template (FXSL for XSLT 1.0) or
the f:transform-and-sum() function (FXSL for XSLT 2.0). In the last
case the necessary XPath expression is:
f:transform-and-sum(f:string-length(), /*/*)
and the complete transformation:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
exclude-result-prefixes="f"
<xsl:import href="../f/func-transform-and-sum.xsl"/>
<xsl:import href="../f/func-standardXpathFunctions.xsl"/>
<!-- to be applied on numList.xml -->
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:value-of select=
"f:transform-and-sum(f:string-length(), /*/*)"/>
</xsl:template>
</xsl:stylesheet>
Cheers,
Dimitre Novatchev.
On 5/27/05, Michael Kay <mike(_at_)saxonica(_dot_)com> wrote:
In XSLT 1.0 the sum() function can only sum the string values of nodes, it
can't sum a set of computed numbers. This means your options are
(a) a two-phase transformation: first create a tree in which the computed
numbers are represented as attributes (typically), then sum over these
attributes
(b) a recursive template to compute the sum
In 2.0, like many things, it's much easier:
sum(child::node()/string-length())
Michael Kay
http://www.saxonica.com/
-----Original Message-----
From: Bovy, Stephen J [mailto:STEPHEN(_dot_)Bovy(_at_)ca(_dot_)com]
Sent: 27 May 2005 07:36
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] How do I get a SUM of the string-length of all
child nodes ??
I am not sure how to do this:
here is what I have which is obviously incorrect:
<xsl:template match="/*/*/*" >
<xsl:param name="rcnt" />
<xsl:choose>
<xsl:when test="position()=1">
<xsl:variable name="csum" select="sum(string-length(.))"/>
rsizes <xsl:value-of select="$rcnt"/> =<xsl:value-of select="$csum"/>;
</xsl:when>
<xsl:otherwise>
bt('<td align="center"> ');
bt('<xsl:value-of select="."/> ');
bt('</td> ');
</xsl:otherwise>
</xsl:choose>
</xsl:template>
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail:
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail:
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--