Archive

Archive for September, 2006

Unique key grouping with multiple input documents and nodesets in variables

September 8, 2006 Leave a comment

The problem

A common requirement in XSL transformations is to group unsorted data by a key unique to each group, and sort it for display. For example:

<?xml version="1.0"?>
<food>
  <item type="Fruit" name="Orange" />
  <item type="Vegetable" name="Cucumber" />
  <item type="Meat" name="Chicken" />
  <item type="Vegetable" name="Carrot" />
  <item type="Vegetable" name="Potato" />
  <item type="Meat" name="Pork" />
  <item type="Fruit" name="Banana" />
  <item type="Fruit" name="Apple" />
</food>

We may typically want to output an HTML table with each food type (Fruit, Meat, Vegetable) as a header with all the items in each food category as table rows/records, ie.

Fruit
Apple
Banana
Orange
Meat
Chicken
Pork
Vegetable
Carrot
Cucumber
Potato

When dealing with a single input document addressed directly (ie. not through a variable), this is a trivial problem for XSL, easily solvable using <xsl:key> and key().

This technique fails when you must group a node-set stored in a variable or in an external document referenced with document() because <xsl:key> does not allow you to use variables or document() in its attributes – it is only capable of indexing the main source document. Additionally, XPath axes we might use for testing uniqueness in a set (typically preceding-sibling:: in an <xsl:for-each> to see if we have found the first occurrence of a new group key) do not function on external documents referenced by document().

So how do we group with XSL variables or multiple input documents? Read more…

Categories: XSL Tags: , ,
%d bloggers like this: