我正在尝试使用xsl:key,使用xsl document()函数查找外部XML文档中的项。如果我不使用document(),而只是合并两个XML文件(在C#中使用XmlDocument),我就可以让xsl:key部分工作。然而,这两个XML文件都很大,在某些情况下我开始出现"内存不足"的错误。我还需要能够使用xls:key,否则这个过程需要几个小时。
在XSLT2.0中,我相信您可以这样做:
<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>
但是,在XSLT1.0中如何实现这一点呢?
您有两种可能性:
没有钥匙
<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>
带钥匙
密钥定义适用于所有文档,但在使用密钥()函数之前需要更改上下文节点:
<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>
另请参阅Mike Kay和Jeni Tennison关于此主题的两个很棒的邮件列表答案