Search

I am trying to do math in my xsl template. Please see the sample data.

<data>
    <chart-data>
        <entry id="1">
            <date>2010-08-02</date>
            <result>positive</result>
            <amount>3</amount>
        </entry>
        <entry id="2">>
            <date>2010-08-03</date>
            <result>positive</result>
            <amount>6</amount>
        </entry>
        <entry id="3">>
            <date>2010-08-04</date>
            <result>negative</result>
            <amount>2</amount>
        </entry>
        <entry id="4">>
            <date>2010-08-05</date>
            <result>positive</result>
            <amount>4</amount>
        </entry>
    </chart-data>   
</data>

I am trying to do is add or subtract (based on weather value of result is negative/positive) to the sum of previous integers.

How would you define the template to see following results based on my sample data:

2010-08-02 … 3 2010-08-03 … 9 2010-08-04 … 7 2010-08-05 … 11

I had to do something similar and created a recursive template. The second solution from this Stack Overflow discussion helped a lot. Hope this points you in the right direction.

There are many ways to do this. Here’s one way:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/">
    <xsl:call-template name="calculate-sum">
        <xsl:with-param name="path" select="/data/chart-data"/>
    </xsl:call-template>
</xsl:template>

<xsl:template name="calculate-sum">

    <!-- Setting the environment parameters -->
    <xsl:param name="path"/>
    <xsl:param name="entry-count" select="count($path/entry)"/>
    <xsl:param name="position" select="1"/>
    <xsl:param name="tally" select="0"/>

    <xsl:param name="result">
        <xsl:choose>
            <xsl:when test="$path/entry[$position]/result = 'positive'">
                <xsl:value-of select="$tally + $path/entry[$position]/amount"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$tally - $path/entry[$position]/amount"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:param>

    <!-- Interim Calculation Output -->
    <p>
        <xsl:text>Result: </xsl:text>
        <xsl:value-of select="$result"/>
    </p>

    <!-- Recursively go over the entries to add/subtract the tally -->
    <xsl:if test="$position &lt; $entry-count">
        <xsl:call-template name="calculate-sum">
            <xsl:with-param name="path" select="$path"/>
            <xsl:with-param name="position" select="$position + 1"/>
            <xsl:with-param name="tally" select="$result"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details