当 xslt 2.0 中存在另一个具有两个相似值的记录时,将计数器更新 +1

Update the counter by +1 when another record with two similar values exists in xslt 2.0

我有以下 xml:

<EmployeeLeaveDataUpsertRequest>
<Row>
    <Emp_id>11</Emp_id>
    <Pay_slip_no>1</Pay_slip_no>
    <Pay_comp>AU_0299</Pay_comp>
    <Hours>136</Hours>
    <Date_from_ec>20170401</Date_from_ec>
    <Date_to_ec>20170429</Date_to_ec>
    <Date_ped> </Date_ped>
    <No_of_period>1</No_of_period>
    <Ma_ind>M</Ma_ind>
    <Fa_ind>N</Fa_ind>
    <Counter>1</Counter>
</Row>
<Row>
    <Emp_id>12</Emp_id>
    <Pay_slip_no>1</Pay_slip_no>
    <Pay_comp>AU_0900</Pay_comp>
    <Hours>40</Hours>
    <Date_from_ec>20170206</Date_from_ec>
    <Date_to_ec>20170210</Date_to_ec>
    <Date_ped> </Date_ped>
    <No_of_period>1</No_of_period>
    <Ma_ind>M</Ma_ind>
    <Fa_ind>N</Fa_ind>
    <Counter>1</Counter>
</Row>
<Row>
    <Emp_id>11</Emp_id>
    <Pay_slip_no>1</Pay_slip_no>
    <Pay_comp>AU_0299</Pay_comp>
    <Hours>8</Hours>
    <Date_from_ec>20170111</Date_from_ec>
    <Date_to_ec>20170115</Date_to_ec>
    <Date_ped> </Date_ped>
    <No_of_period>1</No_of_period>
    <Ma_ind>M</Ma_ind>
    <Fa_ind>N</Fa_ind>
    <Counter>1</Counter>
</Row>

在上面xml你可以看到每条记录都有一个默认值设置为1的元素计数器。

在 Emp_id 和 Pay_comp 相同的事件中,我需要将计数器设置为第一个记录为 1,第二个记录为 2,依此类推。

就像上面的 xml 你可以看到两条记录,其中 Emp_id 是 11 而 Pay_comp 是 AU_0299 - 所以对于第一个设置计数器作为 1,下一个为 2。

输出xml:

<EmployeeLeaveDataUpsertRequest>
<Row>
    <Emp_id>11</Emp_id>
    <Pay_slip_no>1</Pay_slip_no>
    <Pay_comp>AU_0299</Pay_comp>
    <Hours>136</Hours>
    <Date_from_ec>20170401</Date_from_ec>
    <Date_to_ec>20170429</Date_to_ec>
    <Date_ped> </Date_ped>
    <No_of_period>1</No_of_period>
    <Ma_ind>M</Ma_ind>
    <Fa_ind>N</Fa_ind>
    <Counter>1</Counter>
</Row>
<Row>
    <Emp_id>11</Emp_id>
    <Pay_slip_no>1</Pay_slip_no>
    <Pay_comp>AU_0299</Pay_comp>
    <Hours>8</Hours>
    <Date_from_ec>20170111</Date_from_ec>
    <Date_to_ec>20170115</Date_to_ec>
    <Date_ped> </Date_ped>
    <No_of_period>1</No_of_period>
    <Ma_ind>M</Ma_ind>
    <Fa_ind>N</Fa_ind>
    <Counter>2</Counter>
</Row>
<Row>
    <Emp_id>12</Emp_id>
    <Pay_slip_no>1</Pay_slip_no>
    <Pay_comp>AU_0900</Pay_comp>
    <Hours>40</Hours>
    <Date_from_ec>20170206</Date_from_ec>
    <Date_to_ec>20170210</Date_to_ec>
    <Date_ped> </Date_ped>
    <No_of_period>1</No_of_period>
    <Ma_ind>M</Ma_ind>
    <Fa_ind>N</Fa_ind>
    <Counter>1</Counter>
</Row>

我试过for循环但没成功。需要您输入可以实现它的 XSLT 代码

您可以使用一个键来识别重复项,使用 XSLT 3.0(Saxon 9.8 或当前版本的 Altova XMLSpy 和 Raptor 现在支持)它就像:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    exclude-result-prefixes="xs math"
    expand-text="yes"
    version="3.0">

    <xsl:key name="group" match="Row" use="Emp_id , Pay_comp" composite="yes"/>

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

    <xsl:template match="Row[not(. is key('group', (Emp_id , Pay_comp))[1])]/Counter">
        <xsl:copy>{index-of(key('group', (../Emp_id , ../Pay_comp)), ..)}</xsl:copy>
    </xsl:template>

</xsl:stylesheet>

使用 XSLT 2.0,您可以将以上内容转换为

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    exclude-result-prefixes="xs math"
    version="2.0">

    <xsl:key name="group" match="Row" use="concat(Emp_id, '|', Pay_comp)"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Row[not(. is key('group', concat(Emp_id, '|', Pay_comp))[1])]/Counter">
    <xsl:copy>
        <xsl:value-of select="index-of(key('group', concat(../Emp_id, '|', ../Pay_comp)), ..)"/>
    </xsl:copy>
</xsl:template>