0

I generated by a for each the following field: 214.2+428.4+end

I have used substring-before(prices,'+end') but this is a string.

Any ideas how I can take the 214.2+428.4 and sum it up?

input: xml:

<items>
  <item>
    <price>12.50</price>
    <quantity>2</quantity>
  </item>
  <item>
    <price>13.20</price>
    <quantity>3</quantity>
  </item>
</items>

xsl:

<xsl:variable name="total"><xsl:for-each select="item"><xsl:value-of select="price*quantity"></xsl:value-of><xsl:text>+</xsl:text></xsl:for-each>end
</xsl:variable>

output: 25,39.6

Thank you in advanced.

kokos
  • 53
  • 1
  • 7

2 Answers2

0

If the string contains a valid XPath expression (as it does in your example) then you need the ability to dynamically evaluate XPath expressions. This is not a standard feature of XSLT 1.0, however:

  • It's available in XSLT 3.0 with the xsl:evaluate instruction
  • It's available in many XSLT processors as a vendor extension (typically named xx:eval() or xx:evaluate()
  • You might be able to implement it as an extension function yourself using the mechanisms provided by your chosen processor for calling out to extensions.

Alternatively, if you know that the string contains a sequence of numbers separated by plus signs, then you could write a recursive template to extract the tokens, convert them to numbers, and sum them. Or if it's always two numbers, then you don't even need recursion.

As so often happens, it's not enough to have one example of the input your program has to handle; we need to know what the set of all possible inputs is.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • Hello Michael, your alternative is what I need. Is always contains numbers separated by plus signs – kokos Nov 28 '16 at 12:58
  • In that case, the simplest approach is to look for the str:tokenize template in exslt.org, and modify it as needed. – Michael Kay Nov 28 '16 at 15:00
0

I would suggest you try it this way:

XSLT 1.0

<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:strip-space elements="*"/>

<xsl:template match="/items">
    <xsl:variable name="subtotals">
        <xsl:for-each select="item">
            <amount>
                <xsl:value-of select="price * quantity"/>
            </amount>
        </xsl:for-each>
    </xsl:variable>
    <total>
        <xsl:value-of select="sum(exsl:node-set($subtotals)/amount)"/>
    </total>
</xsl:template>

</xsl:stylesheet>

Applied to your example input, the result will be:

<?xml version="1.0" encoding="UTF-8"?>
<total>64.6</total>
michael.hor257k
  • 113,275
  • 6
  • 33
  • 51
  • Cannot transform: Error at line 0: Unregistered function – kokos Nov 28 '16 at 14:35
  • Which processor are you using? If you don't know, see here how to find out: http://stackoverflow.com/questions/25244370/how-can-i-check-which-xslt-processor-is-being-used-in-solr/25245033#25245033 – michael.hor257k Nov 28 '16 at 14:38