This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: XSLT: XPath: Sets
- To: Lee Goddard <Home at LeeGoddard dot com>
- Subject: Re: [xsl] XSLT: XPath: Sets
- From: Jeni Tennison <mail at jenitennison dot com>
- Date: Tue, 27 Feb 2001 17:55:03 +0000
- CC: xsl-list at lists dot mulberrytech dot com
- Organization: Jeni Tennison Consulting Ltd
- References: <5.0.2.1.0.20010227165610.03cdbbc0@pop3.activeisp.com>
- Reply-To: xsl-list at lists dot mulberrytech dot com
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:choose>
<xsl:when test="preceding-sibling::*[name() = name(current())]">
... first of its kind ...
</xsl:when>
<xsl:otherwise>
... later elements ...
</xsl:otherwise>
</xsl:choose>
</xsl:template>
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
with:
count(.|key('elements-by-name', name())[1]) = 1
or:
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
element).
I hope that helps,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list