Фильтрация XPath с помощью функции xsl:key()

Я пытаюсь сравнить два xmls на основе некоторого значения узла.

Ниже приведены два xmls:

a.xml

<?xml version="1.0"?>
<catalog>
    <cd>
        <Test>a</Test>
        <Test1>aa</Test1>
    </cd>
    <cd>
        <Test>e</Test>
        <Test1>ee</Test1>
    </cd>
    <cd>
        <Test>f</Test>
        <Test1>ff</Test1>
    </cd>
    <cd>
        <Test>c</Test>
        <Test1>cc</Test1>
    </cd>
</catalog>

b.xml

<?xml version="1.0"?>
<catalog>
    <cd>
        <Test>a</Test>
        <Test1>aa</Test1>
    </cd>
    <cd>
        <Test>b</Test>
        <Test1>bb</Test1>
    </cd>
    <cd>
        <Test>c</Test>
        <Test1>cc</Test1>
    </cd>
</catalog>

Я пытаюсь сравнить xmls, используя содержимое теста в качестве ключа.

Ниже приведен xsl, который я использую:

<xsl:stylesheet version="2.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="cd" match="cd" use="Test"/>
    <xsl:template match="/catalog">
        <!-- This is working -->
        <xsl:copy>
            <xsl:copy-of select="cd[Test=document('a.xml')/catalog/cd/Test]"/>
        </xsl:copy>
        <!--This is not working-->
        <xsl:copy>
            <xsl:copy-of select="cd[Test=key('cd', cd/Test, document('a.xml'))/Test]"/>
        </xsl:copy>
        <!--This is returning node-set-->
        <xsl:message>
            <xsl:copy-of select="document('a.xml')/catalog/cd/Test"/>
        </xsl:message>
        <!--This is returning node-set-->
        <xsl:message>
            <xsl:copy-of select="key('cd', cd/Test, document('a.xml'))/Test"/>
        </xsl:message>
    </xsl:template>
</xsl:stylesheet>

Выходные данные xsl должны быть общими узлами в обоих xmls, основываясь на значении тестового узла.

Но не уверен, почему тот, кто использует функцию xsl:key(), не работает. Когда я печатаю его отдельно, он показывает правильный набор узлов.

1 ответ

Такое поведение объясняется из-за этих выражений XPath/XSLT в контексте catalog элемент:

  1. Без ключа: cd[Test=document('a.xml')/catalog/cd/Test]

Здесь вы собираетесь выбрать cd элементы, отфильтрованные по предикату:

любой из моих Test childs имеет строковое значение, равное любому из этих Test элементы в a.xml документ

  1. С ключом: cd[Test=key('cd', cd/Test, document('a.xml'))/Test]

Здесь вы собираетесь выбрать cd элементы, отфильтрованные по предикату:

любой из моих Test childs имеет строковое значение, равное любому из этих Test потомки узлов, которые возникают в результате вызова ключа с именем cd в контексте a.xml документ со строковым значением всех моих внуков Test из всех моих детей cd

Эта последняя часть будет пустым набором узлов, оцененным из контекста любого cd элемент.

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