使用xsl:key()函数进行XPath过滤

时间:2019-02-22 20:06:16

标签: xml xslt xpath xslkey

我正在尝试根据某个节点值比较两个xml。

下面是两个xml:

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>

我正在尝试使用 Test 的内容作为关键字来比较xml。

下面是我正在使用的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>

基于 Test 节点值,xsl的输出应该是两个xml中的公共节点。

但是不确定为什么使用xsl:key()函数的那个​​不起作用。当我单独打印它时,它显示了正确的节点集。

1 个答案:

答案 0 :(得分:2)

解释这种行为是由于catalog元素上下文中的那些XPath / XSLT表达式:

  1. 没有密钥:cd[Test=document('a.xml')/catalog/cd/Test]

在这里,您将选择由谓词过滤的cd个元素:

  

我的Test个孩子中的任何一个孩子的字符串值都等于   Test文档中的a.xml个元素

  1. 使用键:cd[Test=key('cd', cd/Test, document('a.xml'))/Test]

在这里,您将选择由谓词过滤的cd个元素:

  

我的Test个孩子中的任何一个孩子的字符串值都等于   在节点中调用名为Test的键所产生的节点的cd个子节点   a.xml文档的上下文,其字符串值为我所有的孙子   我所有孩子中的Test cd

最后一部分将是根据任何cd元素的上下文评估的空节点集。