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

Subject: Re: [xsl] Accessing elements with key via string in variable
From: "Tim Lebo" <timleboxslt@xxxxxxxxx>
Date: Sun, 25 Jun 2006 18:47:39 -0400
Interesting.

I got the output I was looking for by adding a variable in my root template:

<xsl:template match="/">
 <xsl:variable name="input" select="*"/>

and modifying the key access on line 14 to:

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

Is there a cleaner way to do it?

Regards,
Tim

On 6/25/06, Michael Kay <mike@xxxxxxxxxxxx> wrote:
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