mitchpau Posted July 24, 2009 Share Posted July 24, 2009 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 More sharing options...
boen_robot Posted July 24, 2009 Share Posted July 24, 2009 <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 More sharing options...
mitchpau Posted July 24, 2009 Author Share Posted July 24, 2009 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 More sharing options...
boen_robot Posted July 24, 2009 Share Posted July 24, 2009 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 More sharing options...
mitchpau Posted July 27, 2009 Author Share Posted July 27, 2009 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 More sharing options...
boen_robot Posted July 27, 2009 Share Posted July 27, 2009 <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 More sharing options...
mitchpau Posted July 27, 2009 Author Share Posted July 27, 2009 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. Link to comment Share on other sites More sharing options...
boen_robot Posted July 27, 2009 Share Posted July 27, 2009 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 More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.