Jump to content

How To Add Values And Output The Total


mitchpau

Recommended Posts

Hi,Can someone assist with how to add values together in xsl?If I have the following XML file (there could be any number of records):<numbers> <x>5</x></numbers><numbers> <x>3</x></numbers><numbers> <x>4</x></numbers>I'd like to read through the entire file, adding them up as I go along and then output the total at the end e.g. 12Can anyone help provide the code to do this?Cheers !Mitch

Link to comment
Share on other sites

<xsl:value-of select="sum(//numbers/x)" />

or in this case, it could be even more trivial:

<xsl:value-of select="sum(//x)" />

Link to comment
Share on other sites

Crikey, that was quick, thanks ! Can I complicate it slightly to this scenario:<numbers><x>5</x><y>2</y></numbers><numbers><x>3</x><y>6</y></numbers><numbers><x>4</x><y>7</y></numbers>For each run (based on some value of another node not shown) I will have to select either x or y e.g. 2 + 6 + 7 or 5 + 3 + 4Could you advise how I do this as it's no longer a straight sumCheers

Link to comment
Share on other sites

Use a predicate... the contents of the predicate will depend on where exactly the node is, or where the value comes from...For example, if yor full XML was like:

<sets var="x"><numbers><x>5</x><y>2</y></numbers><numbers><x>3</x><y>6</y></numbers><numbers><x>4</x><y>7</y></numbers></sets>

You can do it like:

<xsl:value-of select="sum(//numbers/*[local-name() = /sets/@var])" />

If you have an XSLT parameter with the same value, it's a similar deal:

<xsl:value-of select="sum(//numbers/*[local-name() = $paramName])" />

If you want, you can use the node's position instead of it's name, like:

<xsl:value-of select="sum(//numbers/*[number($paramName)])" />

assuming $paramName contains "1" or "2" as content.

Link to comment
Share on other sites

Thanks for this. Can I elaborate slightly further: My XML looks like this:<fxLeg> <cashFlow1> <currency>CHF</currency> <amount>1512550.00</amount> <buyerPartyReference href="123"/> </cashFlow1> <cashFlow2> <currency>EUR</currency> <amount>1000000.00</amount> <buyerPartyReference href="ABC"/> </cashFlow2></fxLeg><fxLeg> <cashFlow1> <currency>CHF</currency> <amount>1512550.00</amount> <buyerPartyReference href="999"/> </cashFlow1> <cashFlow2> <currency>EUR</currency> <amount>3000000.00</amount> <buyerPartyReference href="DDD"/> </cashFlow2></fxLeg>I need to add the quantites up, but for each record only one amount is relevant e.g. from either cashFlow1 or cashFlow2.To determine which amount to use I use the following in my XSL: <xsl:variable name="customerRef" select="normalize-space( tradeRequest/requesterPartyReference/@href )"/> <xsl:variable name="fxLeg1CashFlow1CorrespondsToCustomer" select="normalize-space( product/fxLeg[ position()=1 ]/cashFlow1/buyerPartyReference/@href )=$customerRef"/> <xsl:choose> <xsl:when test="$fxLeg1CashFlow1CorrespondsToCustomer "> <xsl:value-of select="normalize-space( product/fxLeg[ position()=1 ]/cashFlow1/amount )"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="normalize-space( product/fxLeg[ position()=1 ]/cashFlow2/amount )"/> </xsl:otherwise> </xsl:choose>Can you advise how I can run through the XML using sum and predicates, selecting the appropriate amount each time?Cheers!

Link to comment
Share on other sites

<xsl:value-of select="sum(product/fxLeg[ position()=1 ]/cashFlow1/amount)"/>

perhaps?You see, the idea is not to "run through the XML using sum and predicates". The idea is to gather all nodes you want to sum in a single XPath statement, and use this function once to get the sum of all collected nodes. You need a single XPath statement that maches all amounts you want to sum. With the above example, you'll select all "amount" elements, which are under any "cashFlow1" element that is under the first "fxLeg" element that is under any "product" element, relative to the current context (I'm assuming "/", i.e. the document).

Link to comment
Share on other sites

Thanks. So it's not that simple to total the amounts if they come from a mixture of CashFlow1 or CashFlow2? Just to add, speed isn't an issue here as it's a batch process run once a day.
You can combine several XPath expressions into one by using the "|" character, like:
<xsl:value-of select="sum(product/fxLeg[ position()=1 ]/cashFlow1/amount|product/fxLeg[ position()=1 ]/cashFlow2/amount)"/>

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...