0

In XSLT 1.0/XPATH 1.0, without using any external libraries/node set extensions, I need to be able to sum the cost values of items (for the person's share) of a specific item's type. For example, in the sample XML below, how would I sum the costs for type 'Box' and person 'Andrew'? The expected output for this is '1500' (0.5*1000 + 1*1000).

`<items>
    <item>
        <type>Box</type>
        <cost>1000.00</cost>
        <share>
            <person>
                <name>Jim</name>
                <percent>50</percent>
            </person>
            <person>
                <name>Andrew</name>
                <percent>50</percent>
            </person>
        </share>
    </item>
    <item>
        <type>Box</type>
        <cost>1000.00</cost>
        <share>
            <person>
                <name>Andrew</name>
                <percent>100</percent>
            </person>
        </share>
    </item>
    <item>
        <type>Car</type>
        <cost>2000.00</cost>
        <share>
            <person>
                <name>Andrew</name>
                <percent>100</percent>
            </person>
        </share>
    </item>
    <item>
        <type>Box</type>
        <cost>2000.00</cost>
        <share>
            <person>
                <name>Jim</name>
                <percent>100</percent>
            </person>
        </share>
    </item>
</items>`

In XSLT, I could have a for-each loop:

`<xsl:for-each select="/items/item[type='Box' and share/person/name='Andrew']">
    <xsl:value-of select="share/person[name='Andrew']/percent div 100) * cost"/>
</xsl:for-each>`

but this won't sum the totals. I don't think sum() can be used since it needs to multiple the person's share by the amount for each specific item. I don't know how to store this in a variable with the for-each loop inside due to XSLT restrictions. I think recursion might be able to be used but I am not sure how.

  • Can you edit your question to show what your expected output looks like please? Are you really just interested one particular person/type, or do you actually want to show the totals for all possible items and types? Thanks – Tim C Sep 25 '17 at 07:58

1 Answers1

0

Which XSL extensions, you could do like this:

     <!-- first, store all the computed values to be summed up in a variable -->
     <xsl:variable name="vals">
         <xsl:for-each select="/items/item[type/text() ='Box' and share/person/name/text() = 'Andrew']">
                <val><xsl:value-of select="(cost * share/person[name/text() = 'Andrew']/percent) div 100"/></val>
          </xsl:for-each>
     </xsl:variable>

     <!-- Get the sum of all the values -->
     <xsl:value-of select="sum(exsl:node-set($vals)/*)" />

You also need to add the following declaration on the root element of your stylesheet : xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl"

potame
  • 7,597
  • 4
  • 26
  • 33