I am witnessing a strange behavior with Xalan-j_2_2_D10. 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.
It would be clearer by reading the example below
source XML( This is a sample XML which has a similar structure to what I am
working on)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- File Created on 03-Oct-2001 13:10:34-->
<!DOCTYPE ALBUM_LIST>
<ALBUM_LIST>
<ALBUM ID="Q9001">
<TRACK ID="001"/>
<TRACK ID="002"/>
<TRACK ID="003"/>
</ALBUM>
<ALBUM ID="Q9001">
<TRACK ID="004"/>
<TRACK ID="005"/>
<TRACK ID="003"/>
</ALBUM>
<ALBUM ID="Q9001">
<TRACK ID="006"/>
<TRACK ID="002"/>
<TRACK ID="003"/>
</ALBUM>
</ALBUM_LIST>
I want to extract the list of all unique tracks, which would be tracks with
ID 001,002,003,004,005,006. Here is the XSL that I am using
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:lxslt="http://xml.apache.org/xslt">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:key name="ALBUM_TRACK"
match="ALBUM/TRACK[not(@ID=preceding::node()/@ID)]" use="@ID"/>
<xsl:template match="/" >
<objects>
<xsl:apply-templates select="ALBUM_LIST/ALBUM"/>
</objects>
</xsl:template>
<xsl:template match="ALBUM">
<xsl:for-each
select="TRACK[generate-id()=generate-id(key('ALBUM_TRACK',@ID))]">
<object name="TRACK">
<xsl:value-of select="@ID"/>
</object>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
OUTPUT
<?xml version="1.0" encoding="UTF-8"?>
<objects>
<object name="TRACK">001</object>
<object name="TRACK">002</object>
<object name="TRACK">003</object>
<object name="TRACK">004</object>
<object name="TRACK">005</object>
<object name="TRACK">006</object>
</objects>
This looks like a very simple XSL transformation. Now if I replace
preceding by preceding-sibling in the xsl:key definition, still the OUTPUT
is the SAME. Though there is a significant performance gain. I believe that
this is wrong behavior and probably a bug in Xalan. How can preceding and
preceding-sibling produce the same result. Using preceding-sibling, the
xsl-key should NOT store the unique Tracks, as it cannot look beyond the
parent of Track namely Album, but it seems that preceding-sibling looks into
all the ALBUM elements and thus selects unique TRACK elements.
Also, if I replace preceding:: by following:: axis in the same key, there is
a drastic difference in performance time. I would believe that just by
replacing preceding:: by following:: without any other change, the XSL
transformation time should remain the same, but it is not so in my case.
with preceding::, the total time to run transformation is 30 while with
following:: the time is 8 minutes.
So, looks like there are 2 anomalies, I am using a much large source xml,
about 5MB long.
Please let me know the reason of these two anomalies I am observing and
whether this really is a bug or not
Nisheet