XSLT 1.0 Как использовать xsl:key с функцией document()

Я пытаюсь использовать xsl:key для поиска элементов во внешнем XML-документе, используя функцию XSL document(). Я могу заставить работать часть xsl:key, если вместо использования document () я просто объединю два XML-файла (используя XmlDocument в C#). Однако оба XML-файла очень велики, и в некоторых случаях я начинаю получать ошибки "недостаточно памяти". Также мне нужно иметь возможность использовать xls:key, иначе процесс займет несколько часов.

Я полагаю, что в XSLT 2.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>

Как вы делаете это в XSLT 1.0, хотя?

1 ответ

У вас есть две возможности:

без ключа

<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>

с ключом

Определение ключа применяется ко всем документам, но перед использованием функции key() необходимо изменить узел контекста:

<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>

Также см. Два отличных списка рассылки от Майка Кея и Джени Теннисон по этой теме.

Другие вопросы по тегам