xsl:for-each-group (2)

  1. for-each-group_2-input.xml

  2. <?xml version="1.0"?>
  3. <products>
  4.   <product id="p1" name="Delta" price="3250" stock="4" country="Denmark"/>
  5.   <product id="p2" name="Golf" price="1000" stock="5" country="Germany"/>
  6.   <product id="p3" name="Alpha" price="1200" stock="19" country="Germany"/>
  7.   <product id="p4" name="Foxtrot" price="1500" stock="5" country="Australia"/>
  8.   <product id="p5" name="Tango" price="1225" stock="3" country="Japan"/>
  9. </products>
  1. for-each-group_2-stylesheet.xsl

  2. <?xml version="1.0"?>
  3. <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  4.   <xsl:output indent="yes"/>
  5.   <xsl:template match="/">
  6.     <products>
  7.       <xsl:for-each-group select="products/product" group-by="@country">
  8.       <xsl:sort select="@country"/>
  9.         <xsl:comment>
  10.           <xsl:value-of select="current-grouping-key()"/>
  11.         </xsl:comment>
  12.         <xsl:for-each select="current-group()">
  13.         <xsl:sort select="@stock" data-type="number" order="descending"/>
  14.           <xsl:copy-of select="."/>
  15.         </xsl:for-each>
  16.       </xsl:for-each-group>
  17.     </products>
  18.   </xsl:template>
  19. </xsl:stylesheet>
  1. for-each-group_2-output.xml

  2. <?xml version="1.0" ?>
  3. <products>
  4. <!--Australia-->
  5.   <product id="p4" name="Foxtrot" price="1500" stock="5" country="Australia"/>
  6. <!--Denmark-->
  7.   <product id="p1" name="Delta" price="3250" stock="4" country="Denmark"/>
  8. <!--Germany-->
  9.   <product id="p3" name="Alpha" price="1200" stock="19" country="Germany"/>
  10.   <product id="p2" name="Golf" price="1000" stock="5" country="Germany"/>
  11. <!--Japan-->
  12.   <product id="p5" name="Tango" price="1225" stock="3" country="Japan"/>
  13. </products>

Comment

First we sort the products to get "Australia" first, and inside each group we sort to get the product with highest stock first.

Updated 2009-03-19