[xslt] xsl:key, key() - LibXSLT disagrees with fellow processors

Firstly, thanks for a great and fast XSLT processor.

Secondly, I happened to code something LibXSLT interprets differently
than its fellow processors Saxon 6.5.5 and (Java), Xalan-C
1.10.0 and Sablotron 1.0.3.

All this occurs on Linux Ubuntu, both using the distribution package
1.1.20-0ubuntu2 (version 10120, according to xsltproc -V) and compiling
from source (version 1.1.22, all tests passed, including key tests,
using newest available LibXML2, version 2.6.31).

$ /usr/local/bin/xsltproc -V
Using libxml 20631, libxslt 10122 and libexslt 813
xsltproc was compiled against libxml 20631, libxslt 10122 and libexslt 813
libxslt 10122 was compiled against libxml 20631
libexslt 813 was compiled against libxml 20631

Here's my data. There are a number of ChGr elements identified by @ID
and representing groups of TV channels. Some of those also have a @name.
I call these super-groups and use them to refer to several related
groups. What's related is implicitly defined by document order: The
super-group a given ChGr belongs to is either its own @name or, in the
case of its absence, the first preceding ChGr/@name in axis order.

So we have (1,2,3), (4,5), (6,7,8), (9), (10,11) and (12).

  <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"/>

For easy access, I define a key that returns the super-group ChGr
element node for any given ChGr/@ID.

<xsl:transform version="1.0"
  <xsl:output method="text"/>
  <xsl:key name="super-group" match="ChGr[ name]"
    use=" @ID |
    following-sibling::ChGr[ not(@name) ][
      preceding-sibling::ChGr[ @name ][ 1 ]/@ID = current()/@ID
  <xsl:template match="ChannelGroups">
    <xsl:value-of select="system-property('xsl:vendor')"/>
    <xsl:for-each select="ChGr">
      <xsl:variable name="sg" select="key('super-group', @ID)/@ID"/>
      <xsl:value-of select="@ID"/>
      <xsl:text> </xsl:text>
      <xsl:value-of select="$sg"/>
      <xsl:if test="@ID = $sg"> *super*</xsl:if>

Here's the output.

    Saxon & Co          LibXSLT
    ----------          -------
    1 1 *super*         1 1 *super*
    2 1                 2
    3 1                 3
    4 4 *super*         4 4 *super*
    5 4                 5
    6 6 *super*         6 6 *super*
    7 6                 7
    8 6                 8
    9 9 *super*         9 9 *super*
    10 10 *super*       10 10 *super*
    11 10               11
    12 12 *super*       12 12 *super*

The key() lookups seem to fail where the super-group node is to be found
on the preceding-sibling axis.

I suspect this is a bug in LibXSLT. Is it?

Best regards,

Michael Ludwig

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]