Search code examples
xmlxsltxslt-2.0

How to calculate sum of nodes, with different number format in xsl?


I have the following XML structure:

  <example>
    <data>
       <numberGer>3,40</numberGer>
    </data>
    <data>
      <numberGer>7,40</numberGer>
    </data>
    <data>
       <numberGer>17,40</numberGer>
    </data>
  </example>

I need the sum of all the "numberGer" nodes. The formatting of the number is a problem. Because of the use of "," the function "sum" produces a error. So something like sum(//numberGer) does not work. I can use XSLT 2.0 functions.

I think I need to write a recursive template, which takes the computed value and a list of nodes.

Something like:

<xsl:template name="addGerNumbers">
        <xsl:param name="number"/>
        <xsl:param name="nodes"/>
      <xsl:choose>
        <xsl:when test="$nodes">
          <xsl:variable name="recursive_result">
            ...
           <xsl:call-template name="addGerNumbers">
             ...
            </xsl:call-template>
            </xsl:variable>
          <xsl:value-of select="$number + $recursive_result"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="0"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>

At the end I need a single value as an result.

How to XPath sum() all previous nodes in a XSL for-each loop? Does not work for me, because I need a single number at the end.


Solution

  • A single XPath 2.0 expression is enough:

    <xsl:value-of select="sum( for $i in //numberGer return number(translate( $i, ',','.') ) )"/>
    

    The for loop will translate each value to replace commas with dots, then convert them into numbers. It returns a sequence of numbers that you can now sum normally.