XSLT 2.0基于日期有效性校验分组XML节点实现问题
XSLT日期切片转换问题排查
源XML结构
现有如下结构的源XML:
<CompoundEmployee> <id>176</id> <person> <action>NO CHANGE</action> <created_by>CONV_ADMIN</created_by> <logon_user_id>10005005</logon_user_id> <logon_user_is_active>true</logon_user_is_active> <person_id>176</person_id> <person_id_external>10005005</person_id_external> <personal_information> <end_date>9999-12-31</end_date> <first_name>yutaka</first_name> <first_name_previous>Robbin</first_name_previous> <first_name_alt1>Robbin</first_name_alt1> <start_date>2021-06-03</start_date> </personal_information> <personal_information> <end_date>2021-06-02</end_date> <first_name>wataru</first_name> <first_name_previous>Robbin</first_name_previous> <first_name_alt1>Robbin</first_name_alt1> <start_date>2017-12-06</start_date> </personal_information> <employment_information> <employment_id>136</employment_id> <start_date>2017-12-06</start_date> <user_id>10005005</user_id> <job_information> <action>NO CHANGE</action> <end_date>9999-12-31</end_date> <entry_into_group>2017-12-06</entry_into_group> <event>5</event> <event_reason>DATACONV</event_reason> <excl_executive_sector>false</excl_executive_sector> <fte>1.0</fte> <hazard>false</hazard> <job_code>1000039</job_code> <location>10000069</location> <manager_employment_id>265</manager_employment_id> <manager_id>10005069</manager_id> <manager_person_id>305</manager_person_id> <manager_person_id_external>10005069</manager_person_id_external> <start_date>2019-03-02</start_date> </job_information> </employment_information> </person> <StartDates> <StartDate>2021-06-03</StartDate> <StartDate>2017-12-06</StartDate> <StartDate>2017-12-06</StartDate> <StartDate>2019-03-02</StartDate> </StartDates> </CompoundEmployee>
节点有效范围说明
| 节点类型 | 节点标识 | 生效日期 | 失效日期 |
|---|---|---|---|
| CompoundEmployee(简称CE) | 根节点 | 全局有效 | 全局有效 |
| PersonalInformation | CE/PI01 | 2021-06-03 | 9999-12-31 |
| PersonalInformation | CE/PI02 | 2017-12-06 | 2021-06-02 |
| EmploymentInformation | CE/EI01 | 2017-12-06 | 9999-12-31 |
| Job Information | CE/EI01/JI01 | 2019-03-02 | 9999-12-31 |
转换规则
需要按日期范围生成3条记录,规则如下:
| 生效日期 | 失效日期 | 包含有效节点 |
|---|---|---|
| 2017-12-06 | 2019-03-01 | CE、EI01、PI02 |
| 2019-03-02 | 2021-06-02 | CE、EI01、PI02、JI01 |
| 2021-06-03 | 9999-12-31 | CE、EI01、PI01、JI01 |
规则补充说明
- 收集所有带生效/失效日期的节点(PersonalInfo、JobInfo等),从最早生效日期开始,判断节点在对应时间段是否有效,有效则纳入当期输出
- 新增下一条记录时,上一条记录的失效日期需调整为下一条记录生效日期减1
- 根节点CompoundEmployee及其直属字段默认每条记录都包含,有效节点的内部字段保持原样
预期输出示例
<?xml version="1.0" encoding="UTF-8"?> <Employees> <CompoundEmployee> <StartDate>6-Dec-17</StartDate> <EndDate>1-Mar-19</EndDate> <employment_information> <employment_id>136</employment_id> <start_date>2017-12-06</start_date> <user_id>10005005</user_id> </employment_information> <personal_information> <end_date>2021-06-02</end_date> <first_name>wataru</first_name> <first_name_previous>Robbin</first_name_previous> <first_name_alt1>Robbin</first_name_alt1> <start_date>2017-12-06</start_date> </personal_information> </CompoundEmployee> <CompoundEmployee> <StartDate>2-Mar-19</StartDate> <EndDate>2-Jun-21</EndDate> <employment_information> <employment_id>136</employment_id> <start_date>2017-12-06</start_date> <user_id>10005005</user_id> </employment_information> <personal_information> <end_date>2021-06-02</end_date> <first_name>wataru</first_name> <first_name_previous>Robbin</first_name_previous> <first_name_alt1>Robbin</first_name_alt1> <start_date>2017-12-06</start_date> </personal_information> <job_information> <action>NO CHANGE</action> <end_date>9999-12-31</end_date> <entry_into_group>2017-12-06</entry_into_group> <event>5</event> <event_reason>DATACONV</event_reason> <excl_executive_sector>false</excl_executive_sector> <fte>1.0</fte> <hazard>false</hazard> <job_code>1000039</job_code> <location>10000069</location> <manager_employment_id>265</manager_employment_id> <manager_id>10005069</manager_id> <manager_person_id>305</manager_person_id> <manager_person_id_external>10005069</manager_person_id_external> <start_date>2019-03-02</start_date> </job_information> </CompoundEmployee> <CompoundEmployee> <StartDate>3-Jun-21</StartDate> <EndDate>31-Dec-99</EndDate> <employment_information> <employment_id>136</employment_id> <start_date>2017-12-06</start_date> <user_id>10005005</user_id> </employment_information> <personal_information> <end_date>9999-12-31</end_date> <first_name>yutaka</first_name> <first_name_previous>Robbin</first_name_previous> <first_name_alt1>Robbin</first_name_alt1> <start_date>2021-06-03</start_date> </personal_information> <job_information> <action>NO CHANGE</action> <end_date>9999-12-31</end_date> <entry_into_group>2017-12-06</entry_into_group> <event>5</event> <event_reason>DATACONV</event_reason> <excl_executive_sector>false</excl_executive_sector> <fte>1.0</fte> <hazard>false</hazard> <job_code>1000039</job_code> <location>10000069</location> <manager_employment_id>265</manager_employment_id> <manager_id>10005069</manager_id> <manager_person_id>305</manager_person_id> <manager_person_id_external>10005069</manager_person_id_external> <start_date>2019-03-02</start_date> </job_information> </CompoundEmployee> </Employees>
注:PersonalInfo、EmploymentInfo、JobInfo三类节点出现次数为0到无上限。
现有实现及问题
实现思路
- 按节点的生效/失效日期有效性对节点分组
- 将上一条记录的end_date调整为下一条记录start_date减1
现有XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs"> <xsl:output method="xml" encoding="UTF-8" indent="yes" /> <xsl:template match="@*|node()"> <xsl:for-each select="/CompoundEmployee/StartDates/StartDate"> <Record> <xsl:variable name="cDate" select="/CompoundEmployee/StartDates/xs:date(/StartDate)" /> <xsl:variable name="PIStart" select="/CompoundEmployee/person/personal_information/xs:date(start_date)" /> <xsl:variable name="PIEnd" select="/CompoundEmployee/person/personal_information/xs:date(end_date)" /> <xsl:copy-of select="/CompoundEmployee/person/personal_information[$PIStart <= $cDate and $cDate <= PIEnd]"/> </Record> </xsl:for-each> </xsl:template> </xsl:stylesheet>
错误输出
<?xml version="1.0" encoding="UTF-8"?> <Record/> <Record/> <Record/> <Record/>
问题说明
当前代码日期比较逻辑存在问题,未正确筛选出有效节点,需要排查修正。
内容的提问来源于stack exchange,提问作者VoiceOfReason
相关产品推荐
相关产品推荐

