Re: [xsl] NodeTest expected here - problem with creating xsl:key from document(url)

Subject: Re: [xsl] NodeTest expected here - problem with creating xsl:key from document(url)
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Mon, 26 Aug 2002 18:40:06 -0400
Malcolm,

At 06:02 PM 8/26/2002, you wrote:
I'm trying to create a key based on the contents of an external 'lookup' document, i.e. something like:

<xsl:key name="keyedLookupTable" match="document('LookupTable.xml')/LookupTable/Value" use="@key"/>

Is this allowed? I get a 'NodeTest expected here' error. I've tried a few alternatives (e.g. first assigning the external doc to a variable then using match="msxsl:node-set($myVariable) etc).

Yes, from appearances it seems your processor is balking because it wants a pattern as the value of the declaration's match attribute, and your expression (with the document() function) doesn't follow the rules for a pattern. A pattern matches something, but it's a passive thing -- no nodes are fetched; rather, the pattern merely identifies which nodes *can* match the key (can be returned by the key function). (Patterns are restricted to a subset of XPath expressions that happens to exclude the document() function.) Which nodes actually are returned depends not only on the value supplied, but also the context of the call: the scope of the call being the document that contains the context node for the call (the spec reads the key() function "returns a node-set containing the nodes in the same document as the context node that have a value for the named key equal to [the argument]"). The trick here is *same document* since in your case the lookup table is a different document.


The solution is to match the element with a legal pattern, such as simple match="Value" or match="LookupTable/Value"; then when you call the key, you need to establish your lookup table document as the context for the call. So for example you could try something like:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="keyedLookupTable" match="LookupTable/Value" use="@key"/>

<xsl:variable name="Lookup" select="document('LookupTable.xml')"/>

<xsl:template match="/">
  <Output>
    <xsl:for-each select="/Data/key">
      <xsl:variable name="currentKey" select="."/>
      <xsl:variable name="lookupValue">
        <xsl:for-each select="$Lookup">
        <!-- this for-each does nothing but change the context node for us -->
           <xsl:value-of select="key('keyedLookupTable' , $currentKey)"/>
        </xsl:for-each>
      </xsl:variable>
      <data>
        <xsl:value-of select="$lookupValue"/>
      </data>
    </xsl:for-each>
  </Output>
</xsl:template>

</xsl:stylesheet>

Post again if this doesn't work, if my explanation has only served to mystify you, or if I've totally bollixed up what you need.

Cheers,
Wendell


====================================================================== Wendell Piez mailto:wapiez@xxxxxxxxxxxxxxxx Mulberry Technologies, Inc. http://www.mulberrytech.com 17 West Jefferson Street Direct Phone: 301/315-9635 Suite 207 Phone: 301/315-9631 Rockville, MD 20850 Fax: 301/315-8285 ---------------------------------------------------------------------- Mulberry Technologies: A Consultancy Specializing in SGML and XML ======================================================================


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



Current Thread