This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

SUMMARY: Selecting unique value of an attribute


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>&#xA;</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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]