xsl-list
[Top] [All Lists]

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

2012-12-28 09:08:34
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(_at_)johnmccaskey(_dot_)com> 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(_at_)johnmccaskey(_dot_)com

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--




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

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--