Re: [xsl] current() within a key element's @use

Subject: Re: [xsl] current() within a key element's @use
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxx>
Date: Fri, 28 Dec 2012 10:08:17 -0500
Hi John,

After the holiday lull we may be able to get better information on
this, but in the meantime I may be able to shed a little light in the
darkness.

You are falling into a hole in the specification of XSLT 1.0. I was
remembering that current() was not permitted in xsl:key/@use in XSLT
1.0, but I just looked, and I can't find language in the spec saying
as much. So maybe at some point I learned it was a bad idea due to the
bugs in processors you found.

In any case, assuming that XSLT 2.0 doesn't work for you ... the
workaround is probably to write a literal XPath (i.e., use brute
force) instead of a call to key(). If your processor drags under the
load (which it might, if the traversal is expensive over your data),
you may be able to mitigate these issues by declaring a global
variable that takes you as far down the path from the root to your
target elements as you can get.

So something like

<xsl:variable name="nodes" select="/path/to/nodes"/>

and then (where you'd prefer to use a key):
  select="$nodes[../tagUsage[@render=current()/@xml:id]/@gi]"

Keep in mind that any retrieval using a key can also be done without a
key: it's just likely to be slower (sometimes much slower) and more
opaque to the maintainer. (Except to the maintainer who doesn't know
how to use keys, of course.)

Cheers,
Wendell


On Sun, Dec 23, 2012 at 7:24 PM, John P. McCaskey
<groups@xxxxxxxxxxxxxxxx> wrote:
> I have found inconsistent behavior when using current() in the use attribute
> of a key element.
>
> Shouldn't these
>     <xsl:key name="keyUsingCurrent"   match="color" use="current()/@id"/>
>     <xsl:key name="keyWithoutCurrent" match="color" use="@id"/>
> produce the same set of keys?
>
> With this XML
>    <t>
>       <color id="b">blue</color>
>       <color id="r">red</color>
>    </t>
>
> and this XSLT
>
>   <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
>
>     <xsl:output method="text" indent="no"/>
>
>     <xsl:key name="keyUsingCurrent"   match="color" use="current()/@id"/>
>     <xsl:key name="keyWithoutCurrent" match="color" use="@id"/>
>
>     <xsl:template match="/">
>         (1):<xsl:value-of select="key('keyUsingCurrent', 'b')"/>
>         (2):<xsl:value-of select="key('keyUsingCurrent', 'r')"/>
>
>         (1):<xsl:value-of select="key('keyWithoutCurrent', 'b')"/>
>         (2):<xsl:value-of select="key('keyWithoutCurrent', 'r')"/>
>     </xsl:template>
>
>  </xsl:stylesheet>
>
> Xalan, Saxon and the XSLT processors in Firefox and Internet Explorer return
>
>         (1):blue
>         (2):red
>
>         (1):blue
>         (2):red
>
> which I think is correct;
>
> xsltproc and the XSLT processors in Chrome and Safari return
>
>         (1):
>         (2):
>
>         (1):blue
>         (2):red
>
> which I think is incorrect.
>
> Is my understanding of current() inside @use correct? Am I witnessing a bug
> in code that xsltproc, Chrome and Safari share? If so, to whom would I
> report such a bug? Would doing so make any difference?
>
> I need current() to work inside @use, so that I can have an attribute such
> as
> use="../tagUsage[@render=current()/@xml:id]/@gi". See
> http://stackoverflow.com/questions/13984167/create-xsl-key-by-joining-elements.
> If this is a bug, is there a workaround?
>
> Thanks for any help.
>
> -- JPM
>
> John P. McCaskey, mailbox@xxxxxxxxxxxxxxxx
>



-- 
Wendell Piez | http://www.wendellpiez.com
XML | XSLT | electronic publishing
Eat Your Vegetables
_____oo_________o_o___ooooo____ooooooo_^

Current Thread