Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old August 25th, 2008, 10:30 AM
Authorized User
 
Join Date: Apr 2008
Posts: 70
Thanks: 17
Thanked 1 Time in 1 Post
Send a message via Yahoo to iceandrews
Default Global variable restrictions in the <xsl:key>

I'm trying to use a Global variable in the <xsl:key> instruction. I read that in 2.0 the restrictions on this have been relaxed, but I can't seem to find any documentation on the rules. Obviously, I cannot make use of variants of <xsl:key name="KeyRef" match="$MappingFile/MessageMapping/List" use="@Src"/>

Below is what I'm trying to accomplish.

It should be noted that the "LUT.xsl" contains the global variable $MappingFile and the 'MappingFile.xml' is just a document with the $MappingFile variable as an XML document. But this gives a short example of what I mean.

I will probably have multiple lookup tables coming from multiple external documents. Is there a more elegant way to execute this using 2.0 now that the restrictions have been relaxed?

Code:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:include href="LUT.xsl"/>
    <xsl:variable name="LookupTable" select="document('MappingFile.xml')"/>

    <xsl:key name="KeyRef" match="MessageMapping/List" use="@Src"/>
    <xsl:key name="KeyRefItem" match="MessageMapping/List/Enum" use="@Src"/>

    <xsl:template match="/">
        <xsl:variable name="sKey" select="'Dummy_Enum'"/>
        <xsl:variable name="sList" select="'Dummy_List'"/>


        <Direct>
            <xsl:value-of select="$MappingFile/MessageMapping/List[@Src = $sList]/@Tgt"/>
            <xsl:copy-of select="$MappingFile/MessageMapping/List[@Src = $sList]/Enum[@Src = $sKey]"/>
        </Direct>


        <xsl:for-each select="$LookupTable">
            <Document>
                <xsl:value-of select="key('KeyRefItem',$sKey)[../@Src = $sList]/../@Tgt"/>
                <xsl:copy-of select="key('KeyRefItem',$sKey)"/>
            </Document>
        </xsl:for-each>
    </xsl:template>
</xsL:stylesheet>
 
Old August 25th, 2008, 12:21 PM
mhkay's Avatar
Wrox Author
 
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
Default

You don't need the global variable here. Just define the xsl:key with match="MessageMapping/List". The document that is searched is defined by the context node at the time you call the key() expression, not by the xsl:key definition, and a typical implementation will only build an index for a document the first time you call key() to search that document.

Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer's Reference
 
Old August 25th, 2008, 01:16 PM
Authorized User
 
Join Date: Apr 2008
Posts: 70
Thanks: 17
Thanked 1 Time in 1 Post
Send a message via Yahoo to iceandrews
Default

I see, that provides a little bit of clarity.

I did notice that I can simply put this and it still works properly. Thus eliminating the document() form the XSLT, since the variable is already in the included LUT.xsl

Code:
<xsl:for-each select="$MappingFile">
     <Document>
         <xsl:value-of select="key('KeyRefItem',$sKey)[../@Src = $sList]/../@Tgt"/>
         <xsl:copy-of select="key('KeyRefItem',$sKey)"/>
     </Document>
</xsl:for-each>
So I've been reading the changes of <xsl:key> between 1.0 and 2.0, but I still can't extract the eased restrictions on global variables in the 'match' and 'use' attributes.

In 1.0, using <xsl:for-each> was the only way to "change" the context node so the key() function could reference a LookupTable from an external source (document, included xslt, etc). So there is no way to "pre-build" various indexes, so a single key could be used to match against all of them. The <xsl:for-each> seems like a very "trick" method. It also is restricting the key to the single document tree/context node, rather then the pool of all possible global available trees. (Multiple included xsls, with mulitple LUTs)






Similar Threads
Thread Thread Starter Forum Replies Last Post
Performance for <xsl:import> and <xsl:include> vikkiefd XSLT 2 April 16th, 2008 08:06 AM
Using key() and <xsl:key> freddy XSLT 2 January 18th, 2007 08:55 PM
<xsl:for-each> and key() - help needed muchofrio XSLT 5 April 13th, 2006 09:28 AM
<xsl:key> prints extra string? di98svpa XSLT 6 February 6th, 2006 12:13 PM
<xsl:for-each> with a variable select="attribute" BeneathClouds XSLT 1 August 1st, 2005 03:36 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.