This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
SUMMARY: Selecting unique value of an attribute
- To: xsl-list at mulberrytech dot com
- Subject: SUMMARY: Selecting unique value of an attribute
- From: Paul Terray <terray at 4dconcept dot fr>
- Date: Wed, 23 Aug 2000 19:24:52 +0100
- References: <200008231448.QAA13039@mail.informatik.hu-berlin.de>
- Reply-To: xsl-list at mulberrytech dot com
OK, time for summary.
The problem is the one of doing an index from entries in the text. You want
a list where word do not repeat themselves. The example here use empty tags
with entry as attributes, but you can do with the same algorithms if you
use enclosing tags.
First, My little XML snippet :
<text>
<index entry="thing"/> blablabla <index entry="stuff"/> blabla <index
entry="this"/>
bliblabla<index entry="thing"/> bla bli bla<index entry="this"/> bli <index
entry="stuff"/>
<index entry="thing"/>and bla and bli <index entry="stuff"/>
</text>
I want to get a list with :
-stuff
-thing
-this
There is about two ways of doing it :
- One using the comparison with the preceding element in a sorted subtree,
with a sub-template. This give a solution like this :
"Robert Stupak" <robert@stinklas.lt>
> <xsl:template match="text">
> <xsl:apply-templates select="index">
> <xsl:sort select="@entry"/>
> </xsl:apply-templates>
> </xsl:template>
>
>
> <xsl:template match="index">
> <xsl:if test="not(@entry = preceding::index/@entry)">
> <xsl:value-of select="@entry"/>
> </xsl:if>
> </xsl:template>
This solution is clean to read, although I do prefer the other one for
compacity and probably performance.
- The other solution is more complicated to understand. By using a key, you
group all identical entries, and take only the first of them, like this :
Oliver Becker <obecker@informatik.hu-berlin.de>
>Something like this:
>Define a key for every @entry of index:
><xsl:key name="paul" match="index" use="@entry" />
>
>Then walk through your index elements and choose only the first of
>each group (i.e. each key)
><xsl:for-each
>select="index[generate-id()=generate-id(key('paul',@entry)[1])]">
>
>now you have unique entries which need to be sorted:
><xsl:sort select="@entry" />
>
>Ok - here you are! Output, and that's all:
><xsl:value-of select="@entry" />
>
>
>The complete template is
><xsl:template match="paul">
> <xsl:for-each
> select="index[generate-id()=generate-id(key('paul',@entry)[1])]">
> <xsl:sort select="@entry" />
> <xsl:value-of select="@entry" />
> <xsl:text>
</xsl:text>
> </xsl:for-each>
></xsl:template>
I like that one, because it is rather subtile, and allow me to do a
multiple level index easily.
Another advantage is how easy it is to make hypertext entry beside (you
need one per element in the xml).
However, it is a question of taste and I don't see how one is better than
the other.
Thanks for everybody who answered (including Miloslav Nic, whose first
answer was good enough for me :-)
--
Paul Terray - terray@4dconcept.fr
tel : 01 34 58 70 76
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list