Hi Folks,
Suppose that I want to write an XSLT transform that outputs a bank account
balance after each debit/credit transaction. Here's an XML document that has
the start balance followed by each transaction:
<?xml version="1.0"?>
<BankTransactions>
<StartBalance>100.00</StartBalance>
<Transaction>-5.00</Transaction>
<Transaction>-2.50</Transaction>
<Transaction>10.00</Transaction>
<Transaction>-7.50</Transaction>
</BankTransactions>
The output should be:
95 92.5 102.5 95
I do not believe that this task can be accomplished using xsl:for-each. Do you
agree?
Below are two implementations. The first implementation uses a recursive
function. The second uses xsl:apply-templates to recursively fire a template.
Which implementation is better? Why? Is there a better implementation than the
two shown below? /Roger
----------------------------------------------
IMPLEMENTATION #1: Uses Recursive Function
----------------------------------------------
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ex="http://www.example.org"
version="2.0">
<xsl:output method="text" encoding="US-ASCII" />
<xsl:function name="ex:Balance">
<xsl:param name="starting-balance" />
<xsl:param name="transactions" />
<xsl:choose>
<xsl:when test="empty($transactions)" />
<xsl:otherwise>
<xsl:sequence select="$starting-balance + $transactions[1]" />
<xsl:sequence select="ex:Balance($starting-balance +
$transactions[1], $transactions[position() gt 1])" />
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xsl:template match="BankTransactions">
<xsl:sequence select="ex:Balance(StartBalance, (Transaction))" />
</xsl:template>
</xsl:stylesheet>
--------------------------------------------------------------------------
IMPLEMENTATION #2: Uses xsl:apply-templates to Recursively Fire a Template
--------------------------------------------------------------------------
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="text" encoding="US-ASCII" />
<xsl:template match="BankTransactions">
<xsl:apply-templates select="Transaction[1]">
<xsl:with-param name="starting-balance" select="data(StartBalance)"
/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="Transaction">
<xsl:param name="starting-balance" />
<xsl:sequence select="$starting-balance + data(.)" />
<xsl:if test="following-sibling::Transaction">
<xsl:apply-templates select="following-sibling::Transaction[1]">
<xsl:with-param name="starting-balance"
select="$starting-balance + data(.)" />
</xsl:apply-templates>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
--~------------------------------------------------------------------
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>
--~--