Xslt 1.0 具有多个条件的键xslt

Xslt 1.0 具有多个条件的键xslt,xslt-1.0,xslt-2.0,Xslt 1.0,Xslt 2.0,我在xml中有两个键,其中一个键用于查找firstname,第二个键用于匹配lastname。我的预期输出是,当我将Employee firstname和lastname与多个contractor firstname lastname中的1进行匹配时,我需要检索contractor xml中存在的代理名称,并在Employee中使用它 输入 受雇者 x Y 承包人 x Y Z 承包人 x x A. 承包人 A. Y B 输出 <listofdata> <da

我在xml中有两个键,其中一个键用于查找firstname,第二个键用于匹配lastname。我的预期输出是,当我将Employee firstname和lastname与多个contractor firstname lastname中的1进行匹配时,我需要检索contractor xml中存在的代理名称,并在Employee中使用它

输入


受雇者
x
Y
承包人
x
Y
Z
承包人
x
x
A.
承包人
A.
Y
B
输出

    <listofdata>
    <data>
    <Type>Employee</Type>
    <firstname>x</firstname>
    <lastname>y</lastname>
    <agency>z</agency>
    </data>
    <data>
    <Type>Contractor</Type>
    <firstname>x</firstname>
    <lastname>y</lastname>
    <agency>z</agency>
    </data>
    <data>
    <Type>Contractor</Type>
    <firstname>x</firstname>
    <lastname>x</lastname>
    <agency>a</agency>
    </data>
    <data>
    <Type>Contractor</Type>
    <firstname>a</firstname>
    <lastname>y</lastname>
    <agency>b</agency>
    </data>
    </listofdata>

受雇者
x
Y
Z
承包人
x
Y
Z
承包人
x
x
A.
承包人
A.
Y
B
XSLT:



每当我遇到“雇员”以获得代理时,我都会调用一个模板,我的名字和姓氏是在Contractors中查找名字和姓氏的键。问题是,如果无法得到确切的代理值,无法告诉代理机构firstname和lastname匹配的xslt,我可以在上面得到boolean true false,如果我使用单键,轴可以工作,但不确定如何使其对两个键工作,我想您需要一个复合键,所以在xslt 3中使用Saxon 9.8(任何版本)或者您可以直接使用Altova 2017或2018

<xsl:key name="contract" match="data[Type = 'Contractor']" composite="yes" use="firstname, lastname"/>

<xsl:mode on-no-match="shallow-copy"/>

<xsl:template match="data[Type = 'Employee' and key('contract', (firstname, lastname))]/node()[last()]">
    <xsl:next-match/>
    <xsl:copy-of select="key('contract', ../(firstname, lastname))/agency"/>
</xsl:template>

在XSLT2中,您可以将键中的两个元素值连接在一起,例如
,并使用

<xsl:template match="data[Type = 'Employee' and key('contract', concat(firstname, '|', lastname))]/node()[last()]">
    <xsl:next-match/>
    <xsl:copy-of select="key('contract', concat(../firstname, '|', ../lastname))/agency"/>
</xsl:template>


当然,您必须详细说明身份转换模板。

以及@MartinHonnen提出的解决方案,可以获取由不同键找到的两组值,并形成它们的交集。在XSLT 2.0中,您可以直接使用
intersect
操作符执行此操作:

key('firstName', 'John') intersect key('lastName', 'Smith')
XPath 1.0没有用于集合交集的运算符,但有一个基于集合并集的复杂解决方案:

<xsl:variable name="X" select="key('firstName', 'John')"/>
<xsl:variable name="Y" select="key('lastName', 'Smith')"/>
... select="$X[count(.|$Y) = count($Y)]"/>

... 选择=“$X[计数(.|$Y)=计数($Y)]”/>

非常感谢,我考虑过使用concat,但没有意识到我可以寻找a+b=a+b,而不是a=a和b=b。谢谢,这有助于提高清晰度。我不知道我之前怎么忽略了这一点。我正在使用xlst2,所以我将使用它。我正在做更多的测试,并将其标记为已接受的答案。谢谢
key('firstName', 'John') intersect key('lastName', 'Smith')
<xsl:variable name="X" select="key('firstName', 'John')"/>
<xsl:variable name="Y" select="key('lastName', 'Smith')"/>
... select="$X[count(.|$Y) = count($Y)]"/>