具有多个条件的键xslt

时间:2017-11-24 10:19:54

标签: xslt-1.0 xslt-2.0

我在xml中有两个键,其中一个键用于查找firstname,第二个键用于匹配lastname。我的预期输出是,无论何时,我将员工名字和姓氏与多个承包商名字姓氏中的1匹配,我需要检索承包商xml中存在的代理商名称并在员工中使用

输入

   <listofdata>
    <data>
    <Type>Employee</Type>
    <firstname>x</firstname>
    <lastname>y</lastname>
    </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>

输出

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

XSLT:

<!--get the agency  -->
<xsl:template name="getagency">
  <xsl:variable name="match" select="key('firstname', firstname) 
 and key('lastname', lastname)" />
 <xsl:if test="$match">
                     <xsl:variable name="lastnamevar" select="
 [key('lastname', lastname)] [key('fistname', firstname)]/agency" />
     <agency>
        <xsl:value-of select="$lastnamevar" />
     </agency>
   </xsl:if>
 </xsl:template>

每当我遇到'Employee'来获取代理时,我都会调用模板,而我的名字和姓氏是在Contractors中查找名字和姓氏的键。问题是能够在上面获得布尔值true false,但是不能得到确切的代理值,无法告诉xslt接受firstname和lastname匹配的代理,如果我使用单个键,则轴工作,但不确定如何让它适用于2个键

2 个答案:

答案 0 :(得分:2)

我认为你想要一个复合键,所以在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>

在XSLT 2中,您可以将密钥中的两个元素值连接到例如: <xsl:key name="contract" match="data[Type = 'Contractor']" use="concat(firstname, '|', lastname)"/>并使用例如

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

当然你必须拼出身份转换模板。

答案 1 :(得分:2)

除了@MartinHonnen提出的解决方案之外,还可以获取由不同键找到的两组值,并形成它们的交集。在XSLT 2.0中,您可以使用 string1 = 'Relim' string2 = 'Berkelium' index = [] for i, char1 in enumerate(string2): for j, char2 in enumerate(string1): if char1 == char2: index.append(j) if sorted(index) == index and len(index) == len(string1): result = True else: result = False 运算符直接执行此操作:

intersect

XPath 1.0没有集合交集的运算符,但有一个基于集合联合的复杂解决方案:

key('firstName', 'John') intersect key('lastName', 'Smith')