需要匹配来自不同节点的元素

时间:2014-08-29 14:19:49

标签: xml xslt xslt-2.0

以下是XML的摘录。

<wd:Report_Data xmlns:wd="urn:com.workday.report/CRINT-Outbound">
    <wd:Report_Entry>
        <wd:Worker>
            <wd:Employee_ID>TestId1</wd:Employee_ID>
            <wd:Full_Legal_Name>Test Name1</wd:Full_Legal_Name>
        </wd:Worker>
        <wd:Deduction-Code>TestCode1</wd:Deduction-Code>
        <wd:Result_Line_Amount>100</wd:Result_Line_Amount>
    </wd:Report_Entry>
    <wd:Report_Entry>
        <wd:Worker>
            <wd:Employee_ID>TestId1</wd:Employee_ID>
            <wd:Full_Legal_Name>Test Name1</wd:Full_Legal_Name>
        </wd:Worker>
        <wd:Earning_Code>TestCode1</wd:Earning_Code>
        <wd:Result_Line_Amount>200</wd:Result_Line_Amount>
    </wd:Report_Entry>
</wd:Report_Data>

下面是我的XSLT的片段。

    <xsl:variable name="employeeId">
        <xsl:value-of select="wd:Worker/wd:Employee_ID"/>
    </xsl:variable>

    <xsl:variable name="deductionCode">
        <xsl:value-of select="wd:Earning_Code"/>
    </xsl:variable>

    <OffsetAmount>
        <xsl:variable name="offsetCode" select="$deductionCode"/>

        <xsl:apply-templates select="/wd:Report_Data/wd:Report_Entry[wd:Deduction-Code]">
            <xsl:with-param name="idParam" select="$employeeId"></xsl:with-param>
            <xsl:with-param name="deductionParam" select="$offsetCode"></xsl:with-param>
        </xsl:apply-templates>

    </OffsetAmount>

</xsl:template>

<xsl:template match="/wd:Report_Data/wd:Report_Entry[wd:Deduction-Code]">
    <xsl:param name="idParam"/>
    <xsl:param name="deductionParam"/>
    <xsl:value-of select="/wd:Report_Data/wd:Report_Entry[wd:Worker/wd:Employee_ID = $idParam and wd:Deduction-Code = $deductionParam]/wd:Result_Line_Amount"/>
</xsl:template>

</xsl:stylesheet>

我需要将wd:Deduction-Code从一个节点与另一个节点的匹配wd:Earning_Code相匹配,这样我就可以在输出中包含相应的收入和扣除金额,如下所示。

TestId1, Test Name1, TestCode1, 100, 200

但是使用我的代码,我可以获得TestId1,Test Name1,TestCode1,100而不是200.

TestId1, Test Name1, TestCode1, 100, 

任何建议都会受到欢迎。谢谢!

1 个答案:

答案 0 :(得分:0)

查找包含wd:Report_Entry元素的所有wd:Deduction-Code元素:

<xsl:for-each select="wd:Report_Entry[wd:Deduction-Code]">

然后,输出员工ID及其全名(表示为wd:Worker/*)和wd:Deduction-Code元素的值,用空格分隔:

<xsl:value-of select="string-join(wd:Worker/*|wd:Deduction-Code,' ')"/>

最后,查找wd:Report_Entry元素,其中wd:Earning_Code元素对应两个代码并输出两者的wd:Result_Line_Amount元素:

<xsl:value-of select="string-join(wd:Result_Line_Amount|//wd:Report_Entry[wd:Earning_Code = current()/wd:Deduction-Code]/wd:Result_Line_Amount,' ')"/>

重要提示:下面的样式表假定只有wd:Report_Entry个元素共享相同的代码。

关于XML设计的注释:如输入XML一样,拥有不完整的命名非常麻烦。元素名称带有带连字符的名称,但也带有下划线。

<强>样式表

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
    xmlns:wd="www.wd.com">
    <xsl:output method="text" encoding="UTF-8" indent="yes" />

    <xsl:template match="/wd:Report_Data">

        <xsl:for-each select="wd:Report_Entry[wd:Deduction-Code]">
            <xsl:value-of select="string-join(wd:Worker/*|wd:Deduction-Code,' ')"/>
            <xsl:text> </xsl:text>
            <xsl:value-of select="string-join(wd:Result_Line_Amount|//wd:Report_Entry[wd:Earning_Code = current()/wd:Deduction-Code]/wd:Result_Line_Amount,' ')"/>
        </xsl:for-each>
    </xsl:template>

</xsl:transform>

XML输入

正如我在评论中指出的那样,如果没有名称空间前缀wd:的定义,则输入XML格式不正确。

<wd:Report_Data xmlns:wd="www.wd.com">
    <wd:Report_Entry>
        <wd:Worker>
            <wd:Employee_ID>TestId1</wd:Employee_ID>
            <wd:Full_Legal_Name>Test Name1</wd:Full_Legal_Name>
        </wd:Worker>
        <wd:Deduction-Code>TestCode1</wd:Deduction-Code>
        <wd:Result_Line_Amount>100</wd:Result_Line_Amount>
    </wd:Report_Entry>
    <wd:Report_Entry>
        <wd:Worker>
            <wd:Employee_ID>TestId1</wd:Employee_ID>
            <wd:Full_Legal_Name>Test Name1</wd:Full_Legal_Name>
        </wd:Worker>
        <wd:Earning_Code>TestCode1</wd:Earning_Code>
        <wd:Result_Line_Amount>200</wd:Result_Line_Amount>
    </wd:Report_Entry>
</wd:Report_Data>

XML输出

TestId1 Test Name1 TestCode1 100 200

编辑:另一个样式表版本,使用模板匹配:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
    xmlns:wd="www.wd.com">
    <xsl:output method="text" encoding="UTF-8" indent="yes" />

    <xsl:template match="wd:Report_Entry[wd:Deduction-Code]">
            <xsl:value-of select="string-join(wd:Worker/*|wd:Deduction-Code,' ')"/>
            <xsl:text> </xsl:text>
            <xsl:value-of select="string-join(wd:Result_Line_Amount|//wd:Report_Entry[wd:Earning_Code = current()/wd:Deduction-Code]/wd:Result_Line_Amount,' ')"/>
    </xsl:template>

    <xsl:template match="text()"/>

</xsl:transform>