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="'
'"/> <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
相关产品推荐
相关产品推荐

