Re: [xsl] XSLT: XPath: Sets

Subject: Re: [xsl] XSLT: XPath: Sets
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Tue, 27 Feb 2001 17:55:03 +0000
Hi Lee,

> Is it possible to apply one template to every first-level node
> (/ROOT/*) in a document and have the template output a mark if the
> passed node is the first of its kind? So that in the example below,
> <X a="1"/> would be marked but not <X a="2"/>?

You can test whether a node is the first with that name within its
siblings by seeing if there are any preceding siblings to it that have
the same name, i.e.:

  preceding-sibling::*[name() = name(current())]

So you could do something along the lines of:

<xsl:template match="/*/*">
      <xsl:when test="preceding-sibling::*[name() = name(current())]">
         ... first of its kind ...
         ... later elements ...

If you've got a long document you may find it more efficient to create
a key so that you can quickly retrieve all the elements with a
particular name:

<xsl:key name="elements-by-name" match="/*/*" use="name()" />

You can then test whether the current node is the first with a name

  count(.|key('elements-by-name', name())[1]) = 1


  generate-id() = generate-id(key('elements-by-name', name()))

These both test whether the current element is the first element
returned by the key for that particular key value (the name of the

I hope that helps,


Jeni Tennison

 XSL-List info and archive:

Current Thread