[xsl] Sibling axes in xsl:key/@use ; processor disagreement

Subject: [xsl] Sibling axes in xsl:key/@use ; processor disagreement
From: Michael Ludwig <mlu@xxxxxxxxxxxxx>
Date: Fri, 11 Apr 2008 15:05:52 +0200
I have a number of groups, ChGr, identfied by @ID, which in turn are
assembled in super-groups. A super-group is just a regular ChGr that
also happens to have a @name. The super-group of a given group is to be
found on the self and preceding-sibling axes. Take a look:

<ChannelGroups>
  <ChGr ID="1" name="Hauptsender"/><!-- super-group -->
  <ChGr ID="2"/><!-- part II of this super-group -->
  <ChGr ID="3"/><!-- part III -->
  <ChGr ID="4" name="Regionalsender"/><!-- new super-group -->
  <ChGr ID="5"/><!-- part II, and so on; super-group is: -->
  <ChGr ID="6" name="Lokalsender"/><!-- on self axis -->
  <ChGr ID="7"/><!-- on preceding-sibling axis -->
  <ChGr ID="8"/><!-- and so on -->
  <ChGr ID="9" name="Spartensender"/>
  <ChGr ID="10" name="Infosender"/>
  <ChGr ID="11"/>
  <ChGr ID="12" name="Sportsender"/>
</ChannelGroups>

For easy access, I define a key to find the super-group ChGr node
for any given ChGr/@ID. That would be ChGr 1 for 1, 2 and 3; ChGr 4
for 4 and 5, and so on.

<xsl:transform version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
  <xsl:output method="text"/>
  <xsl:key name="super-group-id" match="ChGr[@name]"
    use=" @ID |
    following-sibling::ChGr[ not(@name) ][
      preceding-sibling::ChGr[ @name ][ 1 ]/@ID = current()/@ID
    ]/@ID"/>
  <xsl:template match="ChannelGroups">
    <xsl:value-of select="system-property('xsl:vendor')"/>
    <xsl:text>&#10;</xsl:text>
    <xsl:for-each select="ChGr">
      <xsl:variable name="sg" select="key('super-group-id', @ID)/@ID"/>
      <xsl:value-of select="@ID"/>
      <xsl:text> </xsl:text>
      <xsl:value-of select="$sg"/>
      <xsl:if test="@ID = $sg"> *super*</xsl:if>
      <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:transform>

This works in SAXON 9.0.0.2 from Saxonica (XSLT 2.0) and Xalan version
1.10.0 (XSLT 1.0).

SAXON 9.0.0.2 from Saxonica
1 1 *super*
2 1
3 1
4 4 *super*
5 4
6 6 *super*
7 6
8 6
9 9 *super*
10 10 *super*
11 10
12 12 *super*

Firstly, any comments on this approach welcome.

Secondly, in LibXSLT (XSLT 1.0), using xsltproc, the output is
different. The key() lookups fail where the super-group node is
to be found on the preceding-sibling axis.

libxslt
1 1 *super*
2
3
4 4 *super*
5
6 6 *super*
7
8
9 9 *super*
10 10 *super*
11
12 12 *super*

What's going on here? Is there some sort of ambiguity in what I've
coded, so processors are free to interpret it one way or the other?

Michael

Current Thread