Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to group and sum values in XSLT

Tags:

xslt

xslt-2.0

For each "agency" node I need to find the "stmt" elements that have the same key1, key2, key3 values and output just one "stmt" node with the "comm" and "prem" values summed together. For any "stmt" elements within that "agency" that don't match any other "stmt" elements based on key1, key2 and key3 I need to output them as is. So after transformation the first "agency" node would only have two "stmt" nodes (one summed) and the second "agency" node would be passed as is because the keys don't match. XSLT 1.0 or 2.0 solutions are ok...though my stylesheet is currently 1.0. Note that the agency nodes could have any number of "stmt" elements that have matching keys which need to be grouped and summed and any number that don't.

<statement>
<agency>
    <stmt>
        <key1>1234</key1>
        <key2>ABC</key2>
        <key3>15.000</key3>
        <comm>75.00</comm>
        <prem>100.00</prem>
    </stmt>
    <stmt>
        <key1>1234</key1>
        <key2>ABC</key2>
        <key3>15.000</key3>
        <comm>25.00</comm>
        <prem>200.00</prem>
    </stmt>
    <stmt>
        <key1>1234</key1>
        <key2>ABC</key2>
        <key3>17.50</key3>
        <comm>25.00</comm>
        <prem>100.00</prem>
    </stmt>
</agency>
<agency>
    <stmt>
        <key1>5678</key1>
        <key2>DEF</key2>
        <key3>15.000</key3>
        <comm>10.00</comm>
        <prem>20.00</prem>
    </stmt>
    <stmt>
        <key1>5678</key1>
        <key2>DEF</key2>
        <key3>17.000</key3>
        <comm>15.00</comm>
        <prem>12.00</prem>
    </stmt>
</agency>

like image 850
johkar Avatar asked May 04 '10 20:05

johkar


People also ask

What does node () do in XSLT?

XSLT current() Function Usually the current node and the context node are the same. However, there is one difference. Look at the following XPath expression: "catalog/cd". This expression selects the <catalog> child nodes of the current node, and then it selects the <cd> child nodes of the <catalog> nodes.

What is regex in XSLT?

The regex-group() function names which matched string you want to use inside of the xsl:matching-substring element; pass it a 1 to get the first, a 2 to get the second, and so forth. The example above uses it to plug the three matched values inside new city, state, and zip elements created for the output.

What is text () in XSLT?

XSLT <xsl:text> The <xsl:text> element is used to write literal text to the output. Tip: This element may contain literal text, entity references, and #PCDATA.


1 Answers

And an XSLT 2.0 solution:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 exclude-result-prefixes="xs"
 >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="node()|@*">
   <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
   </xsl:copy>
 </xsl:template>

 <xsl:template match="agency">
  <agency>
   <xsl:for-each-group select="stmt" group-by=
    "concat(key1, '+', key2, '+', key3)">

    <stmt>
      <xsl:copy-of select=
       "current-group()[1]/*[starts-with(name(),'key')]"/>

       <comm>
         <xsl:value-of select="sum(current-group()/comm)"/>
       </comm>
       <prem>
         <xsl:value-of select="sum(current-group()/prem)"/>
       </prem>
    </stmt>
   </xsl:for-each-group>
  </agency>
 </xsl:template>
</xsl:stylesheet>
like image 177
Dimitre Novatchev Avatar answered Oct 14 '22 19:10

Dimitre Novatchev