Balaganesh Mohanavel
Balaganesh Mohanavel

Reputation: 33

Group by multiple elements in XSLT 1.0

Team I have restrained to use XSLT 1.0 as the current-group() method of XSLT version 2.0 is not available in OIC server.

I have the following source

 <ReadResponse>
   <recset>
      <record>
         <date>date1</date>
         <customer_code>cc</customer_code>
         <item>it1</item>
         <uom></uom>
         <qty>5</qty>
         <amount>15</amount>
         <linetype>LINE</linetype>
      </record>
      <record>
         <date>date1</date>
         <customer_code>cc</customer_code>
         <item>it1</item>
         <uom></uom>
         <qty>10</qty>
         <amount>25</amount>
         <linetype>TAX</linetype>
      </record>
        <record>
         <date>date2</date>
         <customer_code>cc</customer_code>
         <item>it2</item>
         <uom></uom>
         <qty>70</qty>
         <amount>700</amount>
         <linetype>LINE</linetype>
      </record>
   </recset>
</ReadResponse>

target is as follows ( group by date,customer_code,item ) Target amount is sum of all amount's from group, Target "qty" is from source where linetype='LINE' and unitprice is ttarget amount divide by qty.

    <?xml version = '1.0' encoding = 'UTF-8'?>
<targset>
      <targrec>
         <date>date1</date>
         <custcode>cc</custcode>
         <item>it1</item>
         <amount>40</amount>
         <qty>5</qty>
         <unitprice>8</unitprice>
      </targrec>
      <targrec>
         <date>date1</date>
         <custcode>cc</custcode>
         <item>it2</item>
         <amount>700</amount>
         <qty>70</qty>
         <unitprice>10</unitprice>
      </targrec>
   </targset>

Upvotes: 0

Views: 134

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167401

To spell Muechian grouping out for your sample input data:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
  
  <xsl:key name="group" match="record" use="concat(date, '|', customer_code, '|', item)"/>

  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>

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

  <xsl:template match="recset">
    <targset>
      <xsl:apply-templates select="record[generate-id() = generate-id(key('group', concat(date, '|', customer_code, '|', item))[1])]"/>
    </targset>
  </xsl:template>
  
  <xsl:template match="record">
    <targrec>
      <xsl:apply-templates/>
      <unitprice>
        <xsl:value-of select="sum(key('group', concat(date, '|', customer_code, '|', item))/amount) div qty"/>
      </unitprice>
    </targrec>
  </xsl:template>
  
  <xsl:template match="record/amount">
    <xsl:copy>
      <xsl:value-of select="sum(key('group', concat(../date, '|', ../customer_code, '|', ../item))/amount)"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="record/qty">
    <xsl:copy>
      <xsl:value-of select="key('group', concat(../date, '|', ../customer_code, '|', ../item))[linetype = 'LINE']/qty"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="record/customer_code">
    <custcode>
      <xsl:value-of select="."/>
    </custcode>
  </xsl:template>
  
  <xsl:template match="record/uom | record/linetype"/>

</xsl:stylesheet>

Upvotes: 1

Related Questions