Reputation: 145
I have a problem with an XSLT: I like to compute the sum of nodes by a parameter.
The XML source looks like this:
<Documents>
<Document>
<Deleted>0</Deleted>
<DocumentType>2</DocumentType>
<Currency>EUR</Currency>
<CurrencyRate>4.368400</CurrencyRate>
<GrossValue>1000.00</GrossValue>
<DeliveryDate>2016-08-01</DeliveryDate>
<FormOfPayment>2</FormOfPayment>
<DueDate>2016-09-28</DueDate>
</Document>
<Document>
<Deleted>0</Deleted>
<DocumentType>2</DocumentType>
<Currency>EUR</Currency>
<CurrencyRate>4.368400</CurrencyRate>
<GrossValue>2000.00</GrossValue>
<DeliveryDate>2016-08-05</DeliveryDate>
<FormOfPayment>5</FormOfPayment>
<DueDate>2016-09-05</DueDate>
</Document>
<Document>
<Deleted>0</Deleted>
<DocumentType>2</DocumentType>
<Currency>EUR</Currency>
<CurrencyRate>4.368400</CurrencyRate>
<GrossValue>3000.00</GrossValue>
<DeliveryDate>2016-08-30</DeliveryDate>
<FormOfPayment>2</FormOfPayment>
<DueDate>2016-10-29</DueDate>
</Document>
<Document>
<Deleted>0</Deleted>
<DocumentType>2</DocumentType>
<Currency>EUR</Currency>
<CurrencyRate>4.368400</CurrencyRate>
<GrossValue>2500.00</GrossValue>
<DeliveryDate>2016-08-26</DeliveryDate>
<FormOfPayment>5</FormOfPayment>
<DueDate>2016-09-10</DueDate>
</Document>
</Documents>
The result that I need is a sum of amount GrossValue by the parameter FormOfPayment
.
FormOfPayment
is 5, the variable GrossValueCard
should be 4500 FormOfPayment
is 2, the variable GrossValueCash
should be 4000. I tried do this on that way:
<xsl:template name="Suma">
<xsl:param name="index" select="1"/>
<xsl:param name="nodes"/>
<xsl:param name="totalAmount" select="0"/>
<xsl:variable name="currentAmount" select="translate($nodes[$index],',','.')"/>
<xsl:choose>
<xsl:when test="count($nodes)=0">
<xsl:value-of select="0"/>
</xsl:when>
<xsl:when test="$index=count($nodes)">
<xsl:value-of select="$totalAmount + $currentAmount"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="Suma">
<xsl:with-param name="index" select="$index+1"/>
<xsl:with-param name="totalAmount" select="$totalAmount + $currentAmount"/>
<xsl:with-param name="nodes" select="$nodes"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
and it works, but the sum is from all GrossValue
nodes. Can you give me some advice where I should set a parameter to select the sum by FormOfPayment
?
I tried to pick this in condition "when" or "if", but it didn't work.
Upvotes: 1
Views: 1885
Reputation: 117140
The result that I need is a sum of amount GrossValue by the parameter
FormOfPayment
.
So why don't you do simply:
XSLT 1.0
<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:param name="FormOfPayment"/>
<xsl:template match="/Documents">
<total>
<xsl:value-of select="sum(Document[FormOfPayment=$FormOfPayment]/GrossValue)"/>
</total>
</xsl:template>
</xsl:stylesheet>
ADDED
If - as it would seem from your attempt - the amounts in the XML source use decimal comma instead of decimal dot (though the XML shown does not exhibit this problem), and you are limited to XSLT 1.0, I would suggest you do:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="FormOfPayment"/>
<xsl:template match="/Documents">
<xsl:variable name="amounts">
<xsl:for-each select="Document[FormOfPayment=$FormOfPayment]">
<amount>
<xsl:value-of select="translate(GrossValue, ',', '.')"/>
</amount>
</xsl:for-each>
</xsl:variable>
<total>
<xsl:value-of select="sum(exsl:node-set($amounts)/amount)"/>
</total>
</xsl:template>
</xsl:stylesheet>
Upvotes: 2
Reputation: 29052
You can select specific GrossValue
nodes by using a predicate like GrossValue[../FormOfPayment = 'x']
.
To add these selected values use the XSLT 1.0 function sum(...)
with this predicate expression.
A stylesheet could look like this:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" method="xml" />
<xsl:template match="text()" />
<xsl:template match="/Documents">
<xsl:variable name="GrossValueCard2">
<xsl:value-of select="sum(Document/GrossValue[../FormOfPayment = '2']/text())" />
</xsl:variable>
<xsl:variable name="GrossValueCard5">
<xsl:value-of select="sum(Document/GrossValue[../FormOfPayment = '5']/text())" />
</xsl:variable>
Sum of 'FormOfPayment 2's: <xsl:value-of select="$GrossValueCard2" />
Sum of 'FormOfPayment 5's: <xsl:value-of select="$GrossValueCard5" />
</xsl:template>
</xsl:stylesheet>
Upvotes: 0