[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] grouping data


Subject: Re: [xsl] grouping data
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Mon, 3 Dec 2001 09:32:59 +0000

Hi Marco,

> I'm trying to group data using XSLT. I've read that this can be done
> by building a unique lis, but I do not succeed in buiding this
> unique list. Can someone help me out here?

You can do it in several ways. First, there are a few extension
functions that enable you to build lists of unique values from a node
set, for example saxon:distinct() would allow you to do:

  saxon:distinct(/response/elem, saxon:expression('groupname'))

Have a look at your processor's documentation to work out whether it
supports a similar extension function. If it doesn't, or you don't
want to use it (for portability reasons, for example), then you can
collect together those elems whose groupname is not the same as the
groupname of any preceding elem with:

  elem[not(groupname = preceding-sibling::elem/groupname)]

This gets to be inefficient with large numbers of elems. A more
efficient alternative is to create a key that indexes all the elems by
their groupname:

<xsl:key name="elems-by-groupname" match="elem" use="groupname" />

And then work out which elems are the first in the document with a
particular groupname by comparing each to the first elem returned by
the key for that groupname. Given that the elems don't have IDs, you
can compare the identities of the elems using generate-id() as
follows:

  elem[generate-id() =
       generate-id(key('elems-by-groupname', groupname)[1])]

or you can use set logic to see whether a set made up of the elem
you're looking at and the first elem returned by the key has one
member or two members. If it has one member, then the two elems are
the same:

  elem[count(.|key('elems-by-groupname', groupname)[1]) = 1]

I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



Current Thread