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(_at_)CraneSoftwrights(_dot_)com
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