LinkedIn

Saturday, 31 May 2008

How to group with XSLT

Bonjour,

Note: I used Altova 2008 XML Spy which is a great tool.

I just spent a little while trying to understand grouping of data using XSLT.

I first started out using XSLT 2.0 and was quite happy with how easy it was to group until I tried to transform the XSLT with C#. Guess what, .NET 2.0 doesnt support XSLT 2.0 even though W3C says it's the current standard.

Anyway, so I went back to using XSLT 1.0 which was not my friend until now. It's a lot more complex to group using XSLT 1.0 but I eventually got there.

Here is my XSLT:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:key name="cowKey" match="ExpenditureLine" use="CowType" />

<xsl:template match="/">
<html>
<body>

<xsl:for-each select="//ExpenditureLine[generate-id(.)=generate-id(key('cowKey',CowType))]">

<xsl:sort select="count(key('cowKey',CowType))" order="descending" data-type="text"/>
<h2>
<xsl:value-of select="position()"/>
<xsl:text>.</xsl:text>
*<xsl:value-of select="CowType"/>*
<br></br>
<xsl:text> Count: </xsl:text>
<xsl:value-of select="count(key('cowKey',CowType))"/>
</h2>
<ol>
<xsl:for-each select="key('cowKey',CowType)">
<li>
<b><xsl:value-of select="Cow"/>:</b>
<xsl:value-of select="Amount"/>
</li>
</xsl:for-each>
<!--
This nested for-each loops through the City elements that have
the same value for the State attribute as the current City in
the outer for-each loop.
-->
</ol>



</xsl:for-each>
</body>
</html>
</xsl:template>

</xsl:stylesheet>


and here is my XML:

<?xml version="1.0" encoding="UTF-8"?>
<ExpenditureLines>
<ExpenditureLine>
<Cow>RAND</Cow>
<CowType>Capital</CowType>
<Amount>2222</Amount>
</ExpenditureLine>
<ExpenditureLine>
<Cow>LAND7</Cow>
<CowType>Capital</CowType>
<Amount>000005</Amount>
</ExpenditureLine>
<ExpenditureLine>
<Cow>LAND3</Cow>
<CowType>Furniture</CowType>
<Amount>9875</Amount>
</ExpenditureLine>
<ExpenditureLine>
<Cow>ACPB</Cow>
<CowType>Revenue</CowType>
<Amount>1111</Amount>
</ExpenditureLine>
<ExpenditureLine>
<Cow>LAND2</Cow>
<CowType>Furniture</CowType>
<Amount>3333</Amount>
</ExpenditureLine>
<ExpenditureLine>
<Cow>LAND1</Cow>
<CowType>Furniture</CowType>
<Amount>7677</Amount>
</ExpenditureLine>
<ExpenditureLine>
<Cow>YELK</Cow>
<CowType>Other</CowType>
<Amount>000005</Amount>
</ExpenditureLine>
<ExpenditureLine>
<Cow>LAND3</Cow>
<CowType>Furniture</CowType>
<Amount>9875</Amount>
</ExpenditureLine>
</ExpenditureLines>

and here is the result:


1.Furniture
Count: 4


  1. LAND3:9875

  2. LAND2:3333

  3. LAND1:7677

  4. LAND3:9875


2.Capital
Count: 2


  1. RAND:2222

  2. LAND7:000005


3.Revenue
Count: 1


  1. ACPB:1111


4.Other
Count: 1


  1. YELK:000005