RE: [xsl] Accessing elements with key via string in variable

Subject: RE: [xsl] Accessing elements with key via string in variable
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Sun, 25 Jun 2006 23:35:54 +0100
The key() function (with two arguments) selects nodes in the document that
contains the context node. When you do

<xsl:for-each select="$as/a">
     14     <xsl:value-of select="concat(.,'
',count(key('things-by-a',.)),$NL)"/>
     15   </xsl:for-each>

you are selecting things in the document $as, which I suspect is not what
you want.

In XSLT 2.0 you can use the third argument of key() to determine which
document to search.

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

 

> -----Original Message-----
> From: Tim Lebo [mailto:timleboxslt@xxxxxxxxx] 
> Sent: 25 June 2006 23:13
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Accessing elements with key via string in variable
> 
> Hello,
> 
> (The problem exists with the key on line 14)
> 
> I am trying to access 'thing' elements by the value of their 'a'
> element children.
> I do not know what the contents of the 'a' elements will be, 
> so I gather the unique values and iterate through them. When 
> I iterate through, I can print the value, placing the value 
> into the key does not return the 'things' that have 'a' 
> children with that value.
> Additionally, placing a literal string will access the 
> desired nodes, but a variable with the same string content does not.
> 
> The input, current output, desired output, xslt (with line 
> numbers) and xslt are listed below.
> 
> Many thanks,
> Tim
> 
> ======= Input ========
> <things>
>   <thing>
>     <name>thing_1</name>
>     <a>one</a>
>   </thing>
>   <thing>
>     <name>thing_3</name>
>     <a>one</a>
>     <a>two</a>
>   </thing>
>   <thing>
>     <name>thing_4</name>
>     <a>one</a>
>     <a>two</a>
>     <a>three</a>
>   </thing>
>   <thing>
>     <name>thing_5</name>
>     <a>three</a>
>   </thing>
> </things>
> 
> ======= Current Output =========
> Dynamic Selection (DOES NOT WORK)
> one 0
> two 0
> three 0
> 
> ======= Desired output ========
> Hard-coded selection (DESIRED OUTPUT)
> one 3
> two 2
> three 2
> 
> 
> ======== XSLT =========
>       1 <xsl:transform version="2.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
>       2 <xsl:output method="text"/>
>       3 <xsl:key name="things-by-a" match="thing" use="a"/>
>       4
>       5 <xsl:template match="/">
>       6   <xsl:variable name="as">
>       7     <xsl:for-each-group select="//a" group-by=".">
>       8       <a><xsl:value-of select="current-grouping-key()"/></a>
>       9     </xsl:for-each-group>
>      10   </xsl:variable>
>      11
>      12   <xsl:value-of select="concat($NL,'Dynamic Selection (DOES
> NOT WORK)',$NL)"/>
>      13   <xsl:for-each select="$as/a">
>      14     <xsl:value-of select="concat(.,'
> ',count(key('things-by-a',.)),$NL)"/>
>      15   </xsl:for-each>
>      16
>      17   <xsl:value-of select="concat($NL,'Hard-coded selection
> (DESIRED OUTPUT)',$NL)"/>
>      18   <xsl:value-of select="concat('one
> ',count(key('things-by-a','one')),$NL)"/>
>      19   <xsl:value-of select="concat('two
> ',count(key('things-by-a','two')),$NL)"/>
>      20   <xsl:value-of select="concat('three
> ',count(key('things-by-a','three')),$NL)"/>
>      21 </xsl:template>
>      22
>      23 <xsl:variable name="NL">
>      24 <xsl:text>
>      25 </xsl:text>
>      26 </xsl:variable>
>      27
>      28 </xsl:transform>
> 
> ======== XSLT w/o line numbers ========= <xsl:transform 
> version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
> <xsl:output method="text"/>
> <xsl:key name="things-by-a" match="thing" use="a"/>
> 
> <xsl:template match="/">
>   <xsl:variable name="as">
>     <xsl:for-each-group select="//a" group-by=".">
>       <a><xsl:value-of select="current-grouping-key()"/></a>
>     </xsl:for-each-group>
>   </xsl:variable>
> 
>   <xsl:value-of select="concat($NL,'Dynamic Selection (DOES 
> NOT WORK)',$NL)"/>
>   <xsl:for-each select="$as/a">
>     <xsl:value-of select="concat(.,' 
> ',count(key('things-by-a',.)),$NL)"/>
>   </xsl:for-each>
> 
>   <xsl:value-of select="concat($NL,'Hard-coded selection 
> (DESIRED OUTPUT)',$NL)"/>
>   <xsl:value-of select="concat('one 
> ',count(key('things-by-a','one')),$NL)"/>
>   <xsl:value-of select="concat('two 
> ',count(key('things-by-a','two')),$NL)"/>
>   <xsl:value-of select="concat('three
> ',count(key('things-by-a','three')),$NL)"/>
> </xsl:template>
> 
> <xsl:variable name="NL">
> <xsl:text>
> </xsl:text>
> </xsl:variable>
> 
> </xsl:transform>

Current Thread