Search

Hi guys!

I have another tricky transformation that I have not been able to sort out on my own. I was hoping that maybe somebody could help me out

I have a dataset about sports bets and I need to produce some reports based on it. One of the things I need to do is come up with a "conditional total".

First, here's the sample dataset:

<data>
  <entry id="1">
    <event>First Game</event>
    <odds>1.2</odds>
    <outcome>Win</outcome>
  </entry>
  <entry id="2">
    <event>Second Game</event>
    <odds>1.8</odds>
    <outcome>Win</outcome>
  </entry>
  <entry id="3">
    <event>Third Game</event>
    <odds>1.75</odds>
    <outcome>Win</outcome>
  </entry>
  <entry id="4">
    <event>Fourth Game</event>
    <odds>2</odds>
    <outcome>Loss</outcome>
  </entry>
  <entry id="5">
    <event>Fifth Game</event>
    <odds>1.15</odds>
    <outcome>Win</outcome>
  </entry>
</data>

I need to take this data and use it to come up with grand total of these bets. Simple sum won't work here because the actual item to be summed is a result of another equation and the bet amount is param. See, I have to use these two parameters:

<xsl:param name="price" select="100"/>

<xsl:param name="entry-price">
  <xsl:choose>
    <xsl:when test="outcome = 'Win'">
      <xsl:value-of select="$price*$odds"/>
    </xsl:when>
    <xsl:when test="outcome = 'Loss'">
      <xsl:value-of select="-$price"/>
    </xsl:when>
  </xsl:choose>
</xsl:param>

The spreadsheet would look like this:

ID      Entry Price
--------------------
1       120
2       180
3       175
4      -100
5       115
--------------------
        490

So If it's a winning bet then I need to take the odds and multiply it with "price" and if it's loosing bet then it's just -"price"... As you can see above ("entry-price"), It's very easy to do, but now I need to get the grand total of "entry-price".

So, how can I loop through the entries while calculation the bet value and summon it up. I only need to show the grand total value...

Where does the price parameter come from? Is that a hardcoded value, or is it passed in from somewhere?

Ooh, nice one. One way I can think of is the following:

<xsl:template match="/data/entry">
    <xsl:param name="total" select="0"/>
    <xsl:param name="price" select="0"/>
    <xsl:variable name="new-total">
        <xsl:choose>
            <xsl:when test="outcome = 'Win'">
                <xsl:value-of select="$price * odds"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$price * -1"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:choose>
        <xsl:when test="position() = last()">
            <xsl:value-of select="$new-total"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:apply-templates select="/data/entry[position() = current()/position()+1]">
                <xsl:with-param name="total" select="$newtotal"/>
                <xsl:with-param name="price" select="$price"/>
            </xsl:apply-templates>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

which you can then call by using:

<xsl:apply-templates select="/data/entry[position() = 1]">
    <xsl:with-param name="price" select="100"/>
</xsl:apply-templates>

Correction. The above template will not work, here is a working version:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:output method="xml" indent="yes" />
  <xsl:variable name="count" select="count(/data/entry)"/>

  <xsl:template match="/data/entry">
    <xsl:param name="total" select="0"/>
    <xsl:param name="price" select="0"/>
    <xsl:variable name="new-total">
        <xsl:choose>
            <xsl:when test="outcome = 'Win'">
                <xsl:value-of select="$total + ($price * odds)"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$total - ($price)"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:choose>
            <xsl:when test="not(./following-sibling::entry)">
            <xsl:value-of select="$new-total"/>
        </xsl:when>
        <xsl:otherwise>
                  <xsl:apply-templates select="./following-sibling::entry[1]">
                          <xsl:with-param name="total" select="$new-total"/>
                          <xsl:with-param name="price" select="$price"/>
            </xsl:apply-templates>
        </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <xsl:template match="/">
    <xsl:apply-templates select="/data/entry[position() = 1]">
    <xsl:with-param name="price" select="100"/>
    </xsl:apply-templates>
  </xsl:template>

</xsl:stylesheet>

Result can be looked at on xpathr

@designermonkey ... see my original post...

creativedutchmen, your example seems to work and so logical. Doh! I will test it in live environment... And I was messing around with XSLT Keys. :D

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