RE: [xsl] xslt key used with a predicate of an xpath expression

Subject: RE: [xsl] xslt key used with a predicate of an xpath expression
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Fri, 24 Mar 2006 23:57:19 -0000
<xsl:value-of select="concat('The @hex of that object means color ',

$colors/color[@hex=key('objects',idref)/@hex],
                                ' (THIS DOES NOT WORK BUT I WANT IT
TO.)',$NL)"/> 

"idref" is a relative path expression that means child::idref. The context
node is a <color> element, so it looks for a child of the color element
named idref, but there is none.

Moreover, the key function searches the document containing the context
node. But the color element is in a different document from the one you want
to search.

Michael Kay
http://www.saxonica.com/

> -----Original Message-----
> From: Tim Lebo [mailto:timleboxslt@xxxxxxxxx] 
> Sent: 24 March 2006 23:29
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] xslt key used with a predicate of an xpath expression
> 
> Hello,
> 
> Lines 20-22 of the following xsl script do not work as I'd hoped.
> A way to get what I'd hoped is on lines 25-28.
> 
> Is the key used in 20-22 passed directly to 'xpath' before being
> evaluated by 'xslt'?
> Is there a way to accomplish this without creating an extra variable
> as in the solution on 25-28?
> 
> I think it is too hard to explain the problem in English, so please
> excuse my terse canonical description. If you would like more of a
> description, please ask.
> 
> Regards,
> Tim Lebo
> 
> 
> ======== XML input =========
> <?xml version="1.0" encoding="UTF-8"?>
> <root>
>   <object id="obj1" colorhex="#ffffff">
>   </object>
>   <object id="obj2" colorhex="#000000">
>   </object>
>   <object id="obj3" colorhex="#ffffff">
>   </object>
>   <thing>
>           <idref>obj1</idref>
>         </thing>
> </root>
> 
> 
>  ======== XSLT attempt ========
>    1 <?xml version="1.0"?>
>       2 <xsl:transform
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="2.0">
>       3 <xsl:output method="text"/>
>       4
>       5 <xsl:variable name="colors">
>       6   <color hex="#ffffff">White</color>
>       7   <color hex="#000000">Black</color>
>       8 </xsl:variable>
>       9
>      10 <xsl:key name="objects" match="object" use="@id"/>
>      11
>      12 <xsl:template match="/">
>      13   <xsl:apply-templates select="root/thing"/>
>      14 </xsl:template>
>      15
>      16 <xsl:template match="thing">
>      17   <xsl:value-of select="concat('This thing refers to object
> with @id ',idref,$NL)"/>
>      18   <xsl:value-of select="concat('The object with that id has
> @colorhex = ',
>      19                                
> key('objects',idref)/@colorhex,$NL)"/>
>      20   <xsl:value-of select="concat('The @hex of that object means
> color ',
>      21                                
> $colors/color[@hex=key('objects',idref)/@hex],
>      22                                 ' (THIS DOES NOT WORK BUT I
> WANT IT TO.)',$NL)"/>
>      23
>      24   <xsl:comment> The following accomplishes the desired output
> </xsl:comment>
>      25   <xsl:variable name="tempvar" 
> select="key('objects',idref)/@colorhex"/>
>      26   <xsl:value-of select="concat('Value of undesireable variable
> is ',$tempvar,$NL)"/>
>      27   <xsl:value-of select="concat('The round-about way to get the
> color meaning is ',
>      28                                 
> $colors/color[@hex=$tempvar],$NL)"/>
>      29 </xsl:template>
>      30
>      31 <xsl:variable name="NL">
>      32 <xsl:text>
>      33 </xsl:text>
>      34 </xsl:variable>
>      35
>      36 </xsl:transform>
> 
> 
> 
> ======= XSLT without line numbers so you can run it yourself ======
> <?xml version="1.0"?>
> <xsl:transform 
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="2.0">
> <xsl:output method="text"/>
> 
> <xsl:variable name="colors">
>   <color hex="#ffffff">White</color>
>   <color hex="#000000">Black</color>
> </xsl:variable>
> 
> <xsl:key name="objects" match="object" use="@id"/>
> 
> <xsl:template match="/">
>   <xsl:apply-templates select="root/thing"/>
> </xsl:template>
> 
> <xsl:template match="thing">
>   <xsl:value-of select="concat('This thing refers to object with @id
> ',idref,$NL)"/>
>   <xsl:value-of select="concat('The object with that id has 
> @colorhex = ',
>                                 key('objects',idref)/@colorhex,$NL)"/>
>  <xsl:value-of select="concat('The @hex of that object means color ', 
>                              
> $colors/color[@hex=key('objects',idref)/@hex],
>                                 ' (THIS DOES NOT WORK BUT I WANT IT
> TO.)',$NL)"/>
> 
>   <xsl:comment> The following accomplishes the desired output 
> </xsl:comment>
>   <xsl:variable name="tempvar" 
> select="key('objects',idref)/@colorhex"/>
>   <xsl:value-of select="concat('Value of undesireable variable is
> ',$tempvar,$NL)"/>
>   <xsl:value-of select="concat('The round-about way to get the color
> meaning is ',
>                                 $colors/color[@hex=$tempvar],$NL)"/>
> </xsl:template>
> 
> <xsl:variable name="NL">
> <xsl:text>
> </xsl:text>
> </xsl:variable>
> 
> </xsl:transform>

Current Thread