XSLT 2.0: Grouping

While designing the XSLT 2.0 processor for Intel SOA Expressway, our team had to consider how to implement several important new features in the XSLT 2.0 language. In this post we'll look at one of these new features, grouping.

Perhaps the biggest simplification feature in XSLT 2.0, grouping refers to assigning items in a sequence into groups based on some criteria, typically items with the same value. Grouping in XSLT 1.0 was difficult, relying on some tricky XSLT programming. Search for the “Muenchian method” if you are unfamiliar with how this was done previously, or see what Steve Meunch has to say about it.

The XSLT working group addressed this complexity by introducing the very easy to use xsl:for-each-group instruction. You can specify the grouping criteria to use on a sequence of items, the processor will assign the items to groups, then for each group, it will execute the body of the xsl:for-each-group instruction.

Let’s look at an example before looking at the details of this instruction. Suppose we’re formatting for easier viewing the transaction details returned in a SOAP response from a hypothetical financial accounts web service. An example response is shown below.



<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<getTransactionsResponse>
<transactions>
<transaction>
<account>123-456</account>
<amount>32.10</amount>
<date>09/22/2009</date>
</transaction>
<transaction>
<account>123-789</account>
<amount>45.23</amount>
<date>09/22/2009</date>
</transaction>
<transaction>
<account>123-789</account>
<amount>64.00</amount>
<date>09/21/2009</date>
</transaction>
<transaction>
<account>123-456</account>
<amount>24.97.00</amount>
<date>09/21/2009</date>
</transaction>
</transactions >
</getTransactionsResponse >
</soapenv:Body>
</soapenv:Envelope>



Now we can group the transactions by account as follows:

<xsl:for-each-group select=”//transaction” group-by=”account”>

Or we can group by date as follows:

<xsl:for-each-group select=”//transaction” group-by=”date”>

This example showed grouping by like value. The “group-by” attribute specifies the value to use to assign an item to a group. These grouping values are called grouping keys, and the key specification is an XPath expression, so there’s a lot of flexibility in assigning items to groups.

When iterating through the groups, two new functions return the current grouping key, current-grouping-key(), and a sequence of the items in the current group, current-group(). For the example above, we can output an HTML table for each account using these functions to get the headings and table data values:



<xsl:for-each-group select=”//transaction” group-by=”account”>
<table>
Account: <xsl:value-of select=”current-grouping-key()”/>
<tr>
<th>Date</th>
<th>Amount</th>
</tr>
<xsl:for-each select=”current-group()”>
<tr>
<td><xsl:value-of select=”date”/></td>
<td><xsl:value-of select=”amount”/></td>
</tr>
</xsl:for-each>
</table><p/>
</xsl:for-each-group>



Besides grouping by value, it’s possible to group adjacent items, group items that immediately follow a particular item, and group items that immediately precede a particular item. The last two forms of grouping are limited to sequences of nodes and use the group-starting-with and group-ending-with modes. These grouping modes are most useful for processing text-centric XML, where the input document is primarily free flowing text, such as the text of book or play, with elements indicating formatting and some structure information.

From this basic introduction to grouping, I hope it’s obvious that there’s a great deal of power and flexibility built in to this feature. This post has really just scratched the surface. Grouping can be combined with sorting, and for-each-group instructions can be nested to group on multiple levels. As a starting point to learn more, the XSLT 2.0 specification has several good grouping examples.

Étiquettes:
Reportez-vous à notre Notice d'optimisation pour plus d'informations sur les choix et l'optimisation des performances dans les produits logiciels Intel.