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

如何用XSLT的for-each-group按Code合并连续日期休假记录

问题:合并同一Code下连续日期的休假记录

我需要在XSL中实现嵌套分组,按Time_Data/Time_Off/Code分组,将同一Code下日期连续的休假记录合并为一行;非连续的记录(包括单日或多段不连续的连续日期)则单独成行。示例中有两个Code各有连续记录(一个3天、一个4天),还有两个无连续日期的Code记录。


输入XML

<?xml version="1.0" encoding="utf-8"?>
<Output xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <Record>
      <Employee_ID>123456</Employee_ID>
      <Payroll_ID>1111</Payroll_ID>
      <Time_Data>
         <Date>2023-11-04</Date>
         <Day>Saturday</Day>
         <Time_Off>
            <Code>DL</Code>
            <Date>2023-11-04</Date>
            <Quantity>7</Quantity>
            <Unit>HOURS</Unit>
         </Time_Off>
         <Time_Off>
            <Code>RJ</Code>
            <Date>2023-11-04</Date>
            <Quantity>1</Quantity>
            <Unit>HOURS</Unit>
         </Time_Off>
      </Time_Data>
      <Time_Data>
         <Date>2023-11-05</Date>
         <Day>Sunday</Day>
         <Time_Off>
            <Code>DL</Code>
            <Date>2023-11-05</Date>
            <Quantity>7</Quantity>
            <Unit>HOURS</Unit>
         </Time_Off>
         <Time_Off>
            <Code>RJ</Code>
            <Date>2023-11-05</Date>
            <Quantity>1</Quantity>
            <Unit>HOURS</Unit>
         </Time_Off>
      </Time_Data>
      <Time_Data>
         <Date>2023-11-06</Date>
         <Day>Monday</Day>
        <Time_Off>
            <Code>DL</Code>
            <Date>2023-11-06</Date>
            <Quantity>7</Quantity>
            <Unit>HOURS</Unit>
         </Time_Off>
         <Time_Off>
            <Code>RJ</Code>
            <Date>2023-11-06</Date>
            <Quantity>1</Quantity>
            <Unit>HOURS</Unit>
         </Time_Off>
      </Time_Data>
<Time_Data>
         <Date>2023-11-07</Date>
         <Day>Tuesday</Day>
         <Time_Off>
            <Code>RJ</Code>
            <Date>2023-11-07</Date>
            <Quantity>1</Quantity>
            <Unit>HOURS</Unit>
         </Time_Off>
      </Time_Data>
    <Time_Data>
         <Date>2023-11-15</Date>
         <Day>Monday</Day>
        <Time_Off>
            <Code>DL</Code>
            <Date>2023-11-15</Date>
            <Quantity>7</Quantity>
            <Unit>HOURS</Unit>
         </Time_Off>
         <Time_Off>
            <Code>RJ</Code>
            <Date>2023-11-15</Date>
            <Quantity>1</Quantity>
            <Unit>HOURS</Unit>
         </Time_Off>
      </Time_Data>
   </Record>
</Output>

当前使用的XSL转换代码

<xsl:for-each select="Output/Record">
    <xsl:for-each-group select="Time_Data/Time_Off" group-by="concat(Code, '|', Date)">
        <xsl:for-each-group select="current-group()" group-starting-with="*[not(xs:date(Date) = xs:date(preceding-sibling::*[1]/Date) + xs:dayTimeDuration('P1D'))]">
            <xsl:value-of select="format-number(../../Payroll_ID, '00000000')"/>
            <xsl:value-of select="' '"/>
            <xsl:value-of select="format-date(Date, '[D01][M01]')"/>
            <xsl:value-of select="format-date(current-group()[last()]/Date, '[D01][M01]')"/>
            <xsl:value-of select="'    '"/>
            <xsl:value-of select="format-number(sum(current-group()/Quantity) * 100, '0000')"/>
            <xsl:value-of select="Code"/>
            <xsl:value-of select="'TT'"/>
            <xsl:value-of select="$linefeed"/>
        </xsl:for-each-group>
    </xsl:for-each-group>
</xsl:for-each>

当前输出结果

00001111 04110411    0700DLTT
00001111 04110411    0100RJTT
00001111 05110511    0700DLTT
00001111 05110511    0100RJTT
00001111 06110611    0700DLTT
00001111 06110611    0100RJTT
00001111 07110711    0100RJTT
00001111 15111511    0700DLTT
00001111 15111511    0100RJTT

期望输出结果

00001111 04110611    2100DLTT
00001111 04110711    0400RJTT
00001111 15111511    0700DLTT
00001111 15111511    0100RJTT

遇到的问题

我尝试过嵌套多个按Code分组的for-each-group,但无法得到正确的行数,循环迭代次数过多,不清楚正确的分组方式。


有效解决方案

感谢michael.hor257k提供的解答,以下是可行的XSL代码:

<xsl:for-each select="Output/Record">
        <xsl:for-each-group select="Time_Data/Time_Off" group-by="Code">
            <xsl:for-each-group select="current-group()" group-adjacent="xs:date(Date) - position()*xs:dayTimeDuration('P1D')">
                <xsl:value-of select="format-number(../../Payroll_ID, '00000000')"/>
                <xsl:value-of select="' '"/>
                <xsl:value-of select="format-date(Date, '[D01][M01]')"/>
                <xsl:value-of select="format-date(current-group()[last()]/Date, '[D01][M01]')"/>
                <xsl:value-of select="'    '"/>
                <xsl:value-of
                    select="format-number(sum(current-group()/Quantity) * 100, '0000')"/>
                <xsl:value-of select="current-group()[1]/Code"/>
                <xsl:value-of select="'TT'"/>
                <xsl:value-of select="$linefeed"/>
                
            </xsl:for-each-group>
        </xsl:for-each-group>
    </xsl:for-each>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 15:45:54