This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: NodeTest expected here - problem with creating xsl:key from document(url)
- From: Wendell Piez <wapiez at mulberrytech dot com>
- To: xsl-list at lists dot mulberrytech dot com
- Date: Mon, 26 Aug 2002 18:40:06 -0400
- Subject: Re: [xsl] NodeTest expected here - problem with creating xsl:key from document(url)
- Reply-to: xsl-list at lists dot mulberrytech dot com
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@mulberrytech.com
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