[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] XSL 1.0 - sum values taken from corresponding column


Subject: Re: [xsl] XSL 1.0 - sum values taken from corresponding column
From: "Dimitre Novatchev dnovatchev@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 12 Feb 2015 17:28:44 -0000

A non-recursive XSLT 1.0 solution is possible if the xxx:node-set()
extension is used:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:key name="kCol2ByVal" match="col2/cell" use="."/>
 <xsl:template match="/*">
   <xsl:variable name="vrtfPositions">
    <xsl:for-each select="key('kCol2ByVal', 'num')">
      <pos><xsl:value-of select="count(preceding-sibling::*) +1"/></pos>
    </xsl:for-each>
   </xsl:variable>

   <xsl:variable name="vPositions"
select="ext:node-set($vrtfPositions)/pos"/>

   <xsl:value-of select="sum(col1/cell[position() = $vPositions]/@value)"/>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided source XML document:

<root>
 <col1>
  <cell value="1">text</cell>
  <cell value="12">text</cell>
  <cell value="24">text</cell>
  <cell value="100">text</cell>
  <cell value="9">text</cell>
  <cell value="6">text</cell>
 </col1>
 <col2>
  <cell>num</cell>
  <cell>-</cell>
  <cell>num</cell>
  <cell>-</cell>
  <cell>num</cell>
  <cell>num</cell>
 </col2>
 <col3>
  <cell>-</cell>
  <cell>num</cell>
  <cell>num</cell>
  <cell>num</cell>
  <cell>num</cell>
  <cell>-</cell>
 </col3>
</root>

The wanted result: 40   is produced.

--
Cheers,
Dimitre Novatchev




On Thu, Feb 12, 2015 at 9:13 AM, Eliot Kimber ekimber@xxxxxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
> I think that in XSLT 1 the only solution would be to use sibling recursion:
>
> <xsl:template name="sumcells">
>   <xsl:param name="inSum"/>
>   <xsl:variable name="sum" select="$inSum + number(.)"/>
>   <xsl:choose>
>     <xsl:when test="count(following-sibling::cell) = 0">
>       <xsl:value=of select="$sum"/>
>     </xsl:when>
>     <xsl:otherwise>
>      <xsl:for-each select="following-sibling:cell[1]">
>        <xsl:with-param name="inSum" select="$sum"/>
>      </xsl:for-each>
>    </xsl:otherwise>
>   </xsl:choose>
> </xsl:template>
>
> Cheers,
>
> E.
>
> bbbbb
> Eliot Kimber, Owner
> Contrext, LLC
> http://contrext.com
>
>
>
>
> On 2/12/15, 5:42 AM, "Kevin Bird kevinbrianbird@xxxxxxxxx"
> <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>
>>Hello,
>>
>>In <col2>, where cell = num, return the corresponding col1/cell/@value,
>>summing the result.
>>
>><root>
>>       <col1>
>>               <cell value="1">text</cell>
>>               <cell value="12">text</cell>
>>               <cell value="24">text</cell>
>>               <cell value="100">text</cell>
>>               <cell value="9">text</cell>
>>               <cell value="6">text</cell>
>>       </col1>
>>       <col2>
>>               <cell>num</cell>
>>               <cell>-</cell>
>>               <cell>num</cell>
>>               <cell>-</cell>
>>               <cell>num</cell>
>>               <cell>num</cell>
>>       </col2>
>>       <col3>
>>               <cell>-</cell>
>>               <cell>num</cell>
>>               <cell>num</cell>
>>               <cell>num</cell>
>>               <cell>num</cell>
>>               <cell>-</cell>
>>       </col3>
>></root>
>>
>>Sum for <col2> is: 40
>>
>>Sum for <col3> is: 145
>>
>>I'd like an XPath solution, but I don't think that is possible.
>>
>>I tried using keys.
>>
>><xsl:key name="byValue" match="cell" use="/root/col1/cell[position() =
>>count(current()/preceding-sibling::cell)+1]/@value"/>
>>
>>So each cell has the correct value, but I'm struggling to sum the values.
>>Maybe my thinking is wrong.
>>
>>Any help appreciated.
>>
>>--
>>Kevin


Current Thread
Keywords