RE: Different xsl:key implementations (was Re: [xsl] Another key question)

Subject: RE: Different xsl:key implementations (was Re: [xsl] Another key question)
From: "Richard Lander" <rlander@xxxxxxxxxxxxx>
Date: Thu, 17 Oct 2002 15:45:19 -0700
 Ken,

 Yes, I also went to the spec and read the part about the current node being the matched one. As you can likely see, if my key were to work, I could change your code:

<xsl:key name="h2s" match="h2" use="generate-id(preceding-sibling::h1[1])"/>
<xsl:key name="h3s" match="h3" use="generate-id(preceding-sibling::h2[1])"/>
<xsl:key name="h4s" match="h4" use="generate-id(preceding-sibling::h3[1])"/>
<xsl:key name="h5s" match="h5" use="generate-id(preceding-sibling::h4[1])"/>
<xsl:key name="h6s" match="h6" use="generate-id(preceding-sibling::h5[1])"/>

To something like:

<xslt:key name="sections" match="section" use="generate-id(preceding-sibling::*[name() = translate(name(current()),'23456789','12345678')][1])"/>

Ce n'est pas vrai?

I have sent a copy of your mail and my original one to some folks internally to ensure that the correct people get their eyes on the problem. It will be interesting to see if Michael weighs in on the issue ...

Thanks,

Rich
 
-----Original Message-----
From: G. Ken Holman [mailto:gkholman@xxxxxxxxxxxxxxxxxxxx] 
Sent: Thursday, October 17, 2002 2:46 PM
To: XSL List

At 2002-10-17 11:38 -0700, Richard Lander wrote:
>I'm trying to do something with keys and having a bit of trouble. In doing 
>so, I've done some research with some sample data and come up with the 
>following results.
>...
>         <xslt:key name="sections" match="section" 
> use="generate-id(current())"/>
>...
>I get the following result out of MSXML4.
>...
>                 <title>H1</title>
>                 <para>IDAEAWY</para>
>                 <para></para>

I note how the second paragraph is always empty ... no nodes are being 
extracted from the key table ... the question is why and I can think of two 
different reasons and can find processors supporting each reason.

>What should happen?
>
>My main question, is what does 'current()' mean in the context in which 
>I've used it within xsl:key.

First read of section 12.2 of XSLT 1.0:
--------------------------------------

According to the paragraph after the xsl:key prototype, the use= attribute 
is evaluated once for each node that matches the pattern ... it does *not* 
say that the current node list and current node are set to the matched node 
for the purposes of evaluating the use= expression.

During the processing of top-level constructs, the current node is the root 
node, therefore whenever you use current() in the use= expression, the root 
node will be returned.

Note that the test below demonstrates that both Saxon and MSXML uses the 
root node for current() during the evaluation of use=.

Second read of section 12.2 of XSLT 1.0:
---------------------------------------

The final sentence of the first paragraph after the xsl:key prototype 
introduces the bulleted list and the third bullet *does* say the current 
node list and the current node are set to the node being matched, which 
would indicate that current() returns the node being matched.

Section 12.4 states the current() function returns a node-set that has the 
current node as its only member, which must therefore (I would think) be 
the node being matched.

Note that the test below demonstrates that Xalan uses the matched node for 
the second of the two, but not the first which I assume is a bug, but 
definitely isn't returning the root node.

Conclusion
----------

I'm not an implementer, but I would have thought the same as you that 
because of the third bullet the current node and the current node list are 
set to the node being matched therefore the current() function should be 
returning the node being matched therefore the test below should be 
returning a count of two attributes for each access to the key table.

So, I would have thought Xalan was close to getting it right, though for 
some reason not on the first entry, which is wrong.

My gut feel is that both MSXML and Saxon are not returning the correct 
value for the execution of the current() function in the context of use=.

I look forward to hearing comments from the implementers.

..................... Ken


X:\samp>type key-current.xml
<?xml version="1.0" encoding="iso-8859-1"?>
<test att1='1' att2='2' att3='3'>
<x this='a' that='b'>First X</x>
<x this='c' that='d'>Second X</x>
</test>
X:\samp>type key-current.xsl
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                 version="1.0">

<xsl:key name="atts-." match="x" use="count(./@*)"/>
<xsl:key name="atts-current" match="x" use="count(current()/@*)"/>
<xsl:key name="atts-root" match="x" use="count(current()/*/@*)"/>

<xsl:template match="/">
   <xsl:for-each select="key( 'atts-.', '0' )">
     Found 0 attributes in use= expression using "./@*"
   </xsl:for-each>
   <xsl:for-each select="key( 'atts-.', '1' )">
     Found 1 attribute in use= expression using "./@*"
   </xsl:for-each>
   <xsl:for-each select="key( 'atts-.', '2' )">
     Found 2 attributes in use= expression using "./@*"
   </xsl:for-each>
   <xsl:for-each select="key( 'atts-.', '3' )">
     Found 3 attributes in use= expression using "./@*"
   </xsl:for-each>
   <xsl:for-each select="key( 'atts-current', '0' )">
     Found 0 attributes in use= expression using "current()/@*"
   </xsl:for-each>
   <xsl:for-each select="key( 'atts-current', '1' )">
     Found 1 attribute in use= expression using "current()/@*"
   </xsl:for-each>
   <xsl:for-each select="key( 'atts-current', '2' )">
     Found 2 attributes in use= expression using "current()/@*"
   </xsl:for-each>
   <xsl:for-each select="key( 'atts-current', '3' )">
     Found 3 attributes in use= expression using "current()/@*"
   </xsl:for-each>
   <xsl:for-each select="key( 'atts-root', '0' )">
     Found 0 attributes in use= expression using "current()/*/@*"
   </xsl:for-each>
   <xsl:for-each select="key( 'atts-root', '1' )">
     Found 1 attribute in use= expression using "current()/*/@*"
   </xsl:for-each>
   <xsl:for-each select="key( 'atts-root', '2' )">
     Found 2 attributes in use= expression using "current()/*/@*"
   </xsl:for-each>
   <xsl:for-each select="key( 'atts-root', '3' )">
     Found 3 attributes in use= expression using "current()/*/@*"
   </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

X:\samp>call ..\prog\xsltjavasaxon key-current.xml key-current.xsl saxon.out
Invoking Saxon jar....

X:\samp>call ..\prog\xsltjavaxalan key-current.xml key-current.xsl xalan.out
Invoking Xalan/Xerces jar: "key-current.xml" with "key-current.xsl" to 
"xalan.out"

X:\samp>call ..\prog\msxml key-current.xml key-current.xsl msxml.out
Invoking MSXML....

X:\samp>type saxon.out
<?xml version="1.0" encoding="utf-8"?>
     Found 2 attributes in use= expression using "./@*"

     Found 2 attributes in use= expression using "./@*"

     Found 0 attributes in use= expression using "current()/@*"

     Found 0 attributes in use= expression using "current()/@*"

     Found 3 attributes in use= expression using "current()/*/@*"

     Found 3 attributes in use= expression using "current()/*/@*"

X:\samp>type xalan.out
<?xml version="1.0" encoding="UTF-8"?>

     Found 2 attributes in use= expression using "./@*"

     Found 2 attributes in use= expression using "./@*"

     Found 0 attributes in use= expression using "current()/@*"

     Found 2 attributes in use= expression using "current()/@*"

     Found 0 attributes in use= expression using "current()/*/@*"

     Found 0 attributes in use= expression using "current()/*/@*"

X:\samp>type msxml.out
<?xml version="1.0" encoding="UTF-16"?>
     Found 2 attributes in use= expression using "./@*"

     Found 2 attributes in use= expression using "./@*"

     Found 0 attributes in use= expression using "current()/@*"

     Found 0 attributes in use= expression using "current()/@*"

     Found 3 attributes in use= expression using "current()/*/@*"

     Found 3 attributes in use= expression using "current()/*/@*"

X:\samp>rem Done!


--
G. Ken Holman               mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Crane Softwrights Ltd.        http://www.CraneSoftwrights.com/s/
Box 266, Kars, Ontario CANADA K0A-2E0  +1(613)489-0999 (F:-0995)
ISBN 0-13-065196-6                     Definitive XSLT and XPath
ISBN 0-13-140374-5                             Definitive XSL-FO
ISBN 1-894049-08-X Practical Transformation Using XSLT and XPath
ISBN 1-894049-10-1             Practical Formatting Using XSL-FO
Next public training:          2002-12-08,2003-02-03,06,03-03,06


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




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


Current Thread