Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Need to group your data? (Use the Muench Method.)

XSLT and XML

Need to group your data? (Use the Muench Method.)

by  k5tm  Posted    (Edited  )
One frequent requirement is [bi]grouping[/bi]. Grouping is the act of sorting things into a certain order and then coalescing the data for all things that have the same value for the sort key. For example, if you have data for a library of books, you might use grouping to create a report of books sorted by author, with a pretty visual break between authors and a count of books by each author.

In XML, we sort XML elements and use as the sort key the value of an attribute or subordinate element.

XSLT version 2 will have grouping as a [link http://www.w3.org/TR/xslt20/#grouping]native feature[/link], but most of us are using version 1 XSLT processors. So how do we do grouping?

There are many techniques to achieve grouping, many of which are rather brute-force approaches. However, the Muench method is perhaps the most flexible grouping method to be devised for XSLT version 1. The Muench method is named after Steve Muench, who developed this method as the Oracle XML Evangelist.

For example, let's use this XML document taken from a recent thread. The Tek-Tips poster wanted to group entries based on the value of xpos so that he could report all of the ypos values for each xpos.
[code XML data document]
<?xml version="1.0"?>
<availableSeats>
<Table>
<xpos>8</xpos>
<ypos>2</ypos>
<seat_Status>4</seat_Status>
</Table>
<Table>
<xpos>7</xpos>
<ypos>2</ypos>
<seat_Status>4</seat_Status>
</Table>
<Table>
<xpos>7</xpos>
<ypos>1</ypos>
<seat_Status>4</seat_Status>
</Table>
<Table>
<xpos>9</xpos>
<ypos>3</ypos>
<seat_Status>4</seat_Status>
</Table>
</availableSeats>[/code]

The Muench method:

[code XSLT]
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:eek:utput method="html"/>

[color blue]<!-- Add an index (key) that allows selection based on the value of xpos -->[/color]
<xsl:key name="X" match="Table" use="xpos"/>

<xsl:template match="/">
<table border="1">
[color blue]<!-- The outer for-each selects the first Table node for every unique xpos value.
In other words, the outer for-each will iterate exactly once for each unique
value of xpos. -->[/color]

<xsl:for-each select="//Table[generate-id(.)=generate-id(key('X', xpos)[1])]">
<xsl:sort select="xpos"/>
<tr><td><strong><xsl:text>XPOS=</xsl:text><xsl:value-of select="xpos"/></strong></td></tr>
[color blue]<!-- The inner for-each iterates over all nodes that match the outer for-each xpos value -->[/color]
<xsl:for-each select="key('X', xpos)">
<xsl:sort select="ypos"/>
<tr><td><xsl:text>YPOS=</xsl:text><xsl:value-of select="ypos"/></td></tr>
</xsl:for-each>
</xsl:for-each>
</table>
</xsl:template>

</xsl:stylesheet>[/code]

Obviously it is crucial that there be careful matching between the attributes in the xsl:key element and the xsl:for-each and xsl:sort elements.
Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top