Discussion:
Using xsl:key and key() function on xsl:variable lookup data
Russ Loucks
2008-08-20 16:36:03 UTC
Permalink
I have what I think should be a very easy problem to solve but the
solution eludes me.

I have a simple stylesheet that attempts to lookup a value using the
xsl:key tag and key() functions.

I can easily get this to work if the lookup table is in a file and
read it in using the 'document()' function, as follows:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl"
<xsl:variable name="lookupDoc" select="document('lookup.xml')" />

<xsl:key name="lookupKey" match="entry" use="@key"/>

<xsl:template match="dataList/data">

<xsl:variable name="dataKey" select="."/>
data key: <xsl:value-of select="$dataKey" />

<xsl:for-each select="$lookupDoc" >
lookup entry value: <xsl:value-of select="key('lookupKey',
$dataKey)"/>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>

The lookup.xml file:

<entries>
<entry key="key1">lookup entry 1</entry>
<entry key="key2">lookup entry 2</entry>
<entry key="key3">lookup entry 3</entry>
</entries>

The source document to be translated:

<dataList>
<data>key2</data>
<data>key1</data>
</dataList>

Output from this follows (correct):

data key: key2
lookup entry value: lookup entry 2

data key: key1
lookup entry value: lookup entry 1

However, I want to my 'lookupDoc' to be derived from a parameter or
variable, ideally passed down to the stylesheet as a global
parameter. Sort of as follows:

<xsl:variable name="lookupRTF">
<entries>
<entry key="key1">lookup entry 1</entry>
<entry key="key2">lookup entry 2</entry>
<entry key="key3">lookup entry 3</entry>
</entries>
</xsl:variable>

<xsl:variable name="lookupDoc" select="exsl:node-set($lookupRTF)" />

everything else is the same in the stylesheet. When I run this, the
key() function cannot find the key in my lookup doc... Output follows:

data key: key2
lookup entry value:

data key: key1
lookup entry value:

I'm stumped.....


--~------------------------------------------------------------------
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-***@lists.mulberrytech.com>
--~--
G. Ken Holman
2008-08-20 16:52:00 UTC
Permalink
Post by Russ Loucks
I have what I think should be a very easy problem to solve but the
solution eludes me.
The solution is in XSLT 2.0.
Post by Russ Loucks
I have a simple stylesheet that attempts to lookup a value using the
xsl:key tag and key() functions.
I can easily get this to work if the lookup table is in a file and
<xsl:stylesheet version="1.0"
You are using XSLT 1.0.

Below I've modified your stylesheet using XSLT 2.0, then I rewrote
the template rule taking advantage of the new argument introduced in key().

I hope this helps.

. . . . . . . . . . Ken


T:\ftemp>type russ.xml
<dataList>
<data>key2</data>
<data>key1</data>
</dataList>

T:\ftemp>type russ.xsl
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl"
<xsl:variable name="lookupRTF">
<entries>
<entry key="key1">lookup entry 1</entry>
<entry key="key2">lookup entry 2</entry>
<entry key="key3">lookup entry 3</entry>
</entries>
</xsl:variable>

<xsl:key name="lookupKey" match="entry" use="@key"/>

<xsl:template match="dataList/data">

<xsl:variable name="dataKey" select="."/>
data key: <xsl:value-of select="$dataKey" />

<xsl:for-each select="$lookupRTF" >
lookup entry value: <xsl:value-of
select="key('lookupKey', $dataKey)"/>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>

T:\ftemp>call xslt2 russ.xml russ.xsl russ.out

T:\ftemp>type russ.out
<?xml version="1.0" encoding="UTF-8"?>

data key: key2
lookup entry value: lookup entry 2

data key: key1
lookup entry value: lookup entry 1

T:\ftemp>type russ2.xsl
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl"
<xsl:variable name="lookupRTF">
<entries>
<entry key="key1">lookup entry 1</entry>
<entry key="key2">lookup entry 2</entry>
<entry key="key3">lookup entry 3</entry>
</entries>
</xsl:variable>

<xsl:key name="lookupKey" match="entry" use="@key"/>

<xsl:template match="dataList/data">
data key: <xsl:value-of select="." />
lookup entry value: <xsl:value-of select="key('lookupKey',
., $lookupRTF)"/>
</xsl:template>

</xsl:stylesheet>

T:\ftemp>call xslt2 russ.xml russ2.xsl russ2.out

T:\ftemp>type russ2.out
<?xml version="1.0" encoding="UTF-8"?>

data key: key2
lookup entry value: lookup entry 2

data key: key1
lookup entry value: lookup entry 1

T:\ftemp>rem Done!



--
Upcoming XSLT/XSL-FO hands-on courses: Wellington, NZ 2009-01
Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video
G. Ken Holman mailto:***@CraneSoftwrights.com
Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/
Male Cancer Awareness Nov'07 http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers: http://www.CraneSoftwrights.com/legal


--~------------------------------------------------------------------
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-***@lists.mulberrytech.com>
--~--
Russell Loucks
2008-08-20 17:06:36 UTC
Permalink
Holy quick response, Batman.....
Post by G. Ken Holman
Post by Russ Loucks
I have what I think should be a very easy problem to solve but the
solution eludes me.
The solution is in XSLT 2.0.
Bummer. Well, in the meantime, I can get around this quirk by using basic
node-set selects, as in:

<xsl:value-of select="entries/entry[@key=$dataKey]" />

I'm not translating a large amount of values so the performance hit won't be a
big issue. Configurability (e.g., passing the lookup table to the stylesheet
as a parameter) is a higher priority than translation speed.

We can migrate to XSLT 2.0 early next year when we have another major release
scheduled for our software.

Thanks again for a quick response.
R

--~------------------------------------------------------------------
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-***@lists.mulberrytech.com>
--~--

Loading...