I'm trying to use xsl:key to lookup items in an external XML document, using the XSL document() function. I am able to get the xsl:key part to work if, instead of using document(), I just merge the two XML files (using XmlDocument in C#). However both XML files are very large, and I'm starting to get "out of memory" errors in some cases. Also I need to be able to use xls:key, otherwise the process takes hours.
In XSLT 2.0, I believe you can do something like this:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="lookupDoc" select="document('CodeDescriptions.xml')" />
<xsl:key name="LookupDescriptionByCode" match="Code/@description" use="../@code" />
<xsl:template match="ItemCode">
<xsl:call-template name="MakeSpanForCode">
<xsl:with-param name="code" select="text()" />
</xsl:call-template>
</xsl:template>
<xsl:template name="MakeSpanForCode">
<xsl:param name="code" />
<xsl:element name="span">
<xsl:attribute name="title">
<xsl:value-of select="$lookupDoc/key('LookupDescriptionByCode', $code)" />
</xsl:attribute>
<xsl:value-of select="$code" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
How do you accomplish this in XSLT 1.0 though?
You have two possibilities:
<xsl:template name="MakeSpanForCode">
<xsl:param name="code" />
<xsl:element name="span">
<xsl:attribute name="title">
<xsl:value-of select="$lookupDoc/*/Code[@code = $code]/@description" />
</xsl:attribute>
<xsl:value-of select="$code" />
</xsl:element>
</xsl:template>
The key definition applies to all documents, but you need to change the context node before using the key() function:
<xsl:template name="MakeSpanForCode">
<xsl:param name="code" />
<xsl:element name="span">
<xsl:attribute name="title">
<!-- trick: change context node to external document -->
<xsl:for-each select="$lookupDoc">
<xsl:value-of select="key('LookupDescriptionByCode', $code)"/>
</xsl:for-each>
</xsl:attribute>
<xsl:value-of select="$code" />
</xsl:element>
</xsl:template>
Also see two great mailing list answers from Mike Kay and Jeni Tennison on this topic
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With