You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XSLT技术咨询:基于两个条件删除XML重复节点的实现优化

XML重复节点删除XSLT实现

去重规则

  • 规则1:若*[Assignment Number + Legal Entity + Effective Date]* 组合重复,直接删除对应行/节点
  • 规则2:仅当*[Assignment Number + Legal Entity + Payroll Definition + Time Card Required + Overtime Period]* 组合与紧邻的前一节点取值完全相同时删除对应行/节点,若该组合仅在更早的历史节点中存在、但与前一节点不同则保留

前提说明

现有XML已按生效日期完成排序,原有XSLT已经通过preceding-sibling函数实现了规则2的去重逻辑,需要在执行规则2逻辑前,先对每个<wd:Report_Entry>下的<wd:Worker_BP_Events>节点按规则1去重。

XML示例

<wd:Report_Data xmlns:wd="urn:com.workday.report/ERP-PAY-CR-PAYROLL_RELATIONSHIPS">
    <wd:Report_Entry>
        <wd:Worker_BP_Events>
            <wd:COUNTRY_CODE>US</wd:COUNTRY_CODE>
            <wd:UNIQUE_IDENTIFIER>2250403</wd:UNIQUE_IDENTIFIER>
            <wd:ASSIGNMENT_NUMBER>2250403-06202016A14</wd:ASSIGNMENT_NUMBER>
            <wd:LEGISLATIVE_DATA_GROUP>US Care LDG</wd:LEGISLATIVE_DATA_GROUP>
            <wd:LEGAL_ENTITY>A14</wd:LEGAL_ENTITY>
            <wd:EFFECTIVE_START_DATE>2018-12-23</wd:EFFECTIVE_START_DATE>
            <wd:PAYROLL_DEFINITION wd:Descriptor="Biweekly A"> </wd:PAYROLL_DEFINITION>
            <wd:TIMECARD_REQUIRED_FLAG>Y</wd:TIMECARD_REQUIRED_FLAG>
            <wd:OVERTIME_PERIOD wd:Descriptor="TD 7 Days"> </wd:OVERTIME_PERIOD>
            <wd:START_DATE>2018-12-23</wd:START_DATE>

        </wd:Worker_BP_Events>
        <wd:Worker_BP_Events>
            <wd:COUNTRY_CODE>US</wd:COUNTRY_CODE>
            <wd:UNIQUE_IDENTIFIER>2250403</wd:UNIQUE_IDENTIFIER>
            <wd:ASSIGNMENT_NUMBER>2250403-06202016A14</wd:ASSIGNMENT_NUMBER>
            <wd:LEGISLATIVE_DATA_GROUP>US Care LDG</wd:LEGISLATIVE_DATA_GROUP>
            <wd:LEGAL_ENTITY>A14</wd:LEGAL_ENTITY>
            <wd:EFFECTIVE_START_DATE>2019-06-23</wd:EFFECTIVE_START_DATE>
            <wd:PAYROLL_DEFINITION wd:Descriptor="Biweekly A"> </wd:PAYROLL_DEFINITION>
            <wd:TIMECARD_REQUIRED_FLAG>Y</wd:TIMECARD_REQUIRED_FLAG>
            <wd:OVERTIME_PERIOD wd:Descriptor="TD 7 Days"> </wd:OVERTIME_PERIOD>
            <wd:START_DATE>2019-06-23</wd:START_DATE>

        </wd:Worker_BP_Events>
        <wd:Worker_BP_Events>
            <wd:COUNTRY_CODE>US</wd:COUNTRY_CODE>
            <wd:UNIQUE_IDENTIFIER>2250403</wd:UNIQUE_IDENTIFIER>
            <wd:ASSIGNMENT_NUMBER>2250403-06202016A14</wd:ASSIGNMENT_NUMBER>
            <wd:LEGISLATIVE_DATA_GROUP>US Care LDG</wd:LEGISLATIVE_DATA_GROUP>
            <wd:LEGAL_ENTITY>A14</wd:LEGAL_ENTITY>
            <wd:EFFECTIVE_START_DATE>2019-06-23</wd:EFFECTIVE_START_DATE>
            <wd:PAYROLL_DEFINITION wd:Descriptor="Biweekly A"> </wd:PAYROLL_DEFINITION>
            <wd:TIMECARD_REQUIRED_FLAG>Y</wd:TIMECARD_REQUIRED_FLAG>
            <wd:OVERTIME_PERIOD wd:Descriptor="TD 14 Days"> </wd:OVERTIME_PERIOD>
            <wd:START_DATE>2019-06-23</wd:START_DATE>

        </wd:Worker_BP_Events>
        <wd:Worker_BP_Events>
            <wd:COUNTRY_CODE>US</wd:COUNTRY_CODE>
            <wd:UNIQUE_IDENTIFIER>2250403</wd:UNIQUE_IDENTIFIER>
            <wd:ASSIGNMENT_NUMBER>2250403-06202016A09</wd:ASSIGNMENT_NUMBER>
            <wd:LEGISLATIVE_DATA_GROUP>US Care LDG</wd:LEGISLATIVE_DATA_GROUP>
            <wd:LEGAL_ENTITY>A09</wd:LEGAL_ENTITY>
            <wd:EFFECTIVE_START_DATE>2020-03-15</wd:EFFECTIVE_START_DATE>
            <wd:PAYROLL_DEFINITION wd:Descriptor="Biweekly A"> </wd:PAYROLL_DEFINITION>
            <wd:TIMECARD_REQUIRED_FLAG>Y</wd:TIMECARD_REQUIRED_FLAG>
            <wd:OVERTIME_PERIOD wd:Descriptor="TD 7 Days"> </wd:OVERTIME_PERIOD>
            <wd:START_DATE>2020-03-15</wd:START_DATE>

        </wd:Worker_BP_Events>

        <wd:Worker>
            <wd:EFFECTIVE_END_DATE>4712-12-31</wd:EFFECTIVE_END_DATE>
            <wd:CLOSE_DATE>4712-12-31</wd:CLOSE_DATE>
        </wd:Worker>
    </wd:Report_Entry>
</wd:Report_Data>

原有XSLT代码

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    xmlns:wd="urn:com.workday.report/ERP-PAY-CR-PAYROLL_RELATIONSHIPS"
    version="2.0">
    <xsl:output method="text"/>
    <xsl:variable name="linefeed" select="'&#xD;&#xA;'"/>
    <xsl:variable name="pipe" select="'|'"/>

    
    <xsl:param name="quote">"</xsl:param>
    <xsl:template match="/">


        <!--  File Detail Layout  -->
        <xsl:for-each select="wd:Report_Data/wd:Report_Entry/wd:Worker_BP_Events[not(concat(wd:ASSIGNMENT_NUMBER,wd:LEGAL_ENTITY,wd:PAYROLL_DEFINITION/@wd:Descriptor,wd:TIMECARD_REQUIRED_FLAG,wd:OVERTIME_PERIOD/@wd:Descriptor)=preceding-sibling::*[1]/concat(wd:ASSIGNMENT_NUMBER,wd:LEGAL_ENTITY,wd:PAYROLL_DEFINITION/@wd:Descriptor,wd:TIMECARD_REQUIRED_FLAG,wd:OVERTIME_PERIOD/@wd:Descriptor))]">
            <xsl:call-template name="Write-Detail-Record"/>
        </xsl:for-each>
    </xsl:template>
    
        

    <xsl:template name="Write-Detail-Record">

        
        <xsl:value-of select="wd:COUNTRY_CODE"/>
        <xsl:value-of select="$pipe"/>
        
        <xsl:value-of select="wd:UNIQUE_IDENTIFIER"/>
        <xsl:value-of select="$pipe"/>
        
        <xsl:value-of select="wd:ASSIGNMENT_NUMBER"/>
        <xsl:value-of select="$pipe"/>
        
        <xsl:value-of select="wd:LEGISLATIVE_DATA_GROUP"/>
        <xsl:value-of select="$pipe"/>
        
        
        <xsl:value-of select="wd:LEGAL_ENTITY"/>
        <xsl:value-of select="$pipe"/>
        
        
        <xsl:value-of select="format-date(wd:EFFECTIVE_START_DATE,'[Y0001]-[M01]-[D01]')"/>
        <xsl:value-of select="$pipe"/>
        
        <xsl:value-of select="format-date(../wd:Worker/wd:EFFECTIVE_END_DATE,'[Y0001]-[M01]-[D01]')"/>
        <xsl:value-of select="$pipe"/>
        
        
        <xsl:value-of select="wd:PAYROLL_DEFINITION/@wd:Descriptor"/>
        <xsl:value-of select="$pipe"/>
        
        <xsl:value-of select="wd:TIMECARD_REQUIRED_FLAG"/>
        <xsl:value-of select="$pipe"/>
        
        <xsl:value-of select="wd:OVERTIME_PERIOD/@wd:Descriptor"/>
        <xsl:value-of select="$pipe"/>
        
        <xsl:value-of select="format-date(wd:START_DATE,'[Y0001]-[M01]-[D01]')"/>
        <xsl:value-of select="$pipe"/>
        
        <xsl:value-of select="format-date(../wd:Worker/wd:CLOSE_DATE,'[Y0001]-[M01]-[D01]')"/>
        <xsl:value-of select="$pipe"/>
        
        
        <xsl:value-of select="format-date(wd:FINAL_CLOSE_DATE,'[Y0001]-[M01]-[D01]')"/>
        <xsl:value-of select="$pipe"/>
        
        <xsl:value-of select="format-date(../wd:Worker/wd:LAST_STANDARD_PROCESS_DATE,'[Y0001]-[M01]-[D01]')"/>
        
        
        
        <xsl:value-of select="$linefeed"/>
        
        
    </xsl:template>
</xsl:stylesheet>

修改方案

只需要在原有xsl:for-each的节点过滤条件中,新增规则1的判断即可,修改后的xsl:for-each代码如下:

<!--  File Detail Layout  -->
<xsl:for-each select="wd:Report_Data/wd:Report_Entry/wd:Worker_BP_Events
[not(concat(wd:ASSIGNMENT_NUMBER,wd:LEGAL_ENTITY,wd:EFFECTIVE_START_DATE) = preceding-sibling::wd:Worker_BP_Events/concat(wd:ASSIGNMENT_NUMBER,wd:LEGAL_ENTITY,wd:EFFECTIVE_START_DATE))]
[not(concat(wd:ASSIGNMENT_NUMBER,wd:LEGAL_ENTITY,wd:PAYROLL_DEFINITION/@wd:Descriptor,wd:TIMECARD_REQUIRED_FLAG,wd:OVERTIME_PERIOD/@wd:Descriptor)=preceding-sibling::*[1]/concat(wd:ASSIGNMENT_NUMBER,wd:LEGAL_ENTITY,wd:PAYROLL_DEFINITION/@wd:Descriptor,wd:TIMECARD_REQUIRED_FLAG,wd:OVERTIME_PERIOD/@wd:Descriptor))]">
    <xsl:call-template name="Write-Detail-Record"/>
</xsl:for-each>

逻辑说明:新增的第一层过滤先将所有Assignment Number + Legal Entity + EFFECTIVE_START_DATE组合重复的节点排除,仅保留每个组合的第一个节点,再执行原有规则2的紧邻节点去重逻辑,完全符合需求。


内容的提问来源于stack exchange,提问作者abishek rao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 13:24:06