Re: sort/group/count problem

Subject: Re: sort/group/count problem
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Sun, 5 Nov 2000 10:48:04 +0000

> 1. Is the XML structure attached efficient?  Should I put most of the
> elements, such as all children of <item>, to be attributes instead?

The elements vs. attributes debate is a long and sordid one, which has
usually focused on the factors of:

(a) logical purity (meta information should be attributes)
(b) verboseness (attributes take less space)
(c) structure (attributes don't have internal structure)
(d) ordering (attributes can't be ordered)
(e) data typing (elements can't be data typed in DTDs)
(f) scope (in DTDs, attributes are local to their element)

and so on. There's a full description and discussion on Robin Cover's
pages at

I think it's a really interesting question from the XSLT perspective.
There are a couple of factors to bear in mind:

1. The built-in templates mean that templates are automatically
applied to any elements in your XML, but not to attributes. Thus, it's
easier to fall back on (and locally override) automatic processing if
you store your information in elements than if you store it in

2. The built-in template for elements is marginally more
processor intensive than the built-in template for attributes, so
simply applying templates to the bits you need is slightly quicker if
you use attributes than if you use elements.  For example:

<xsl:apply-templates select="description" />

would match the built-in element-matching template, which would apply
templates to the content of the element, which would match the
text-matching template, which would give the value of the element.

<xsl:apply-templates select="@description" />

on the other hand, would match the attribute-matching template, which
would give the value of the attribute.

In your position, I'd almost certainly put itemid and batchid as id
attributes on item and batch.  Other than that, though, I don't know
enough about your data to comment.

> 2. How should I sort all items within each batch based on itemid, and
> display each of the group separately?

In general, you can sort using xsl:sort:

  <xsl:for-each select="item">
    <xsl:sort select="itemid" />

but for the grouping that you want to do as well, and:
> 3. How should I count all distinctive itemid within each batch?
> I was able to figure out "count(//itemid[not(.=preceding::itemid)])" count
> all disctinctive itemid, but it was for all items in the XML document, not
> within the scope of each batch.

I'd recommend the Muenchian grouping method.  There's a more detailed
description on my pages at but

1. define a key to group the things you want to group in the way you
want to group them.  Given that you want to group by batch as well as
itemid, this would be something like:

<xsl:key name="items"
         use="concat(parent::itemlist/parent::batch/batchid, itemid)" />

2. identify unique items within a batch with the expression:

  item[generate-id() =
       generate-id(key('items', concat(../../batchid, itemid))[1])]

3. identify the other items within the same batch with a particular
itemid with the expression:

  key('items', concat(../../batchid, itemid))

I hope that this helps get you started,


Jeni Tennison

 XSL-List info and archive:

Current Thread