Re: [xsl] Confusion with the usage of preceding and preceding-sibling axe s

Subject: Re: [xsl] Confusion with the usage of preceding and preceding-sibling axe s
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Fri, 19 Oct 2001 09:44:35 +0100
Hi Nisheet,

> I am witnessing a strange behavior with the understanding the
> concept of preceding and preceding-sibling axis. I am using xsl:key
> to construct a list of unique elements and later on using
> xsl:for-each to display these unique results. I am observing that
> both preceding and preceding-sibling are producing the same output,
> which is surprising since, preceding-sibling is supposed to return
> all the siblings that occur before the context node in the document
> order and belong to the same parent.

The reason that you're getting the same behaviour whichever axis
you're using is that later on in your stylesheet, you're only
selecting the first TRACK with a particular @ID, with the path:

  TRACK[generate-id()=generate-id(key('ALBUM_TRACK',@ID))]

With this line, you are selecting all the TRACK elements that are the
same as the first TRACK element that you get when you call the
'ALBUM_TRACK' key with the TRACK's ID. If you use the preceding::
axis, then the only TRACK elements that the key contains are those
that are the first in the document with that particular ID. If you use
the preceding-sibling:: axis then it contains all the TRACKs that have
a unique ID within each ALBUM. Either way it doesn't matter because
the first TRACK that's retrieved by the key will be the first TRACK in
the document with that particular ID.

So, you would also get exactly the same result (probably faster) if
you set up the key to index *all* the TRACK elements in your document,
with:

<xsl:key name="ALBUM_TRACK" match="ALBUM/TRACK" use="@ID"/>

There doesn't seem to be anything wrong with your understanding of the
preceding:: and preceding-sibling:: axes, just with your understanding
of what the key is doing, I think.

To test out preceding:: and preceding-sibling::, forget about the key
and try using the following in the xsl:for-each instead:

<!-- using preceding:: -->
<xsl:template match="ALBUM">
    <xsl:for-each select="TRACK[not(@ID = preceding::TRACK/@ID)]">
      <object name="TRACK">
        <xsl:value-of select="@ID"/>
      </object>
    </xsl:for-each>
</xsl:template>

<!-- using preceding-sibling:: -->
<xsl:template match="ALBUM">
    <xsl:for-each select="TRACK[not(@ID = preceding-sibling::TRACK/@ID)]">
      <object name="TRACK">
        <xsl:value-of select="@ID"/>
      </object>
    </xsl:for-each>
</xsl:template>

I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread