Фильтрация 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
элемент:
- Без ключа:
cd[Test=document('a.xml')/catalog/cd/Test]
Здесь вы собираетесь выбрать cd
элементы, отфильтрованные по предикату:
любой из моих
Test
childs имеет строковое значение, равное любому из этихTest
элементы вa.xml
документ
- С ключом:
cd[Test=key('cd', cd/Test, document('a.xml'))/Test]
Здесь вы собираетесь выбрать cd
элементы, отфильтрованные по предикату:
любой из моих
Test
childs имеет строковое значение, равное любому из этихTest
потомки узлов, которые возникают в результате вызова ключа с именемcd
в контекстеa.xml
документ со строковым значением всех моих внуковTest
из всех моих детейcd
Эта последняя часть будет пустым набором узлов, оцененным из контекста любого cd
элемент.