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

如何用XSLT实现按日期分组聚合及取最后值的XML转换?

用XSLT实现XML分组聚合转换需求

需要将给定XML转换为指定的CSV格式,每条输出记录包含:

  • 员工姓名
  • 职位
  • 日期(同一日期仅出现一次)
  • 该日期下最后一条In_Time(无则留空)
  • 该日期下最后一条Out_Time(无则留空)
  • 当日所有Hours的总和

此前尝试先按ID分组,再按Details/Date分组,但未能成功将同日期的记录归为一组。

示例输出

Bill,President,2025-07-01-07:00,2025-07-01T08:00:00-04:00,2025-07-01T12:00:00-04:00,4
Scott,Vice President,2025-07-03-07:00,,8
Scott,Vice President,2025-07-07-07:00,,8
Scott,Vice President,2025-07-08-07:00,,8 

示例XML

<Data>    
    <Entry>
        <ID>1</ID>
        <Name>Bill</Name>
        <Title>President</Title>
        <Details>
            <Date>2025-07-01-07:00</Date>
            <In_Time>2025-07-01T08:00:00-04:00</In_Time>
            <Out_Time>2025-07-01T12:00:00-04:00</Out_Time>
            <Hours>4</Hours>
            <Type>PTO</Type>
        </Details>
        <Details>
            <Date>2025-07-01-07:00</Date>
            <In_Time>2025-07-01T08:00:00-04:00</In_Time>
            <Out_Time>2025-07-01T15:00:00-04:00</Out_Time>
            <Hours>2</Hours>
            <Type>PTO</Type>
        </Details>
        <Details>
            <Date>2025-07-01-07:00</Date>
            <In_Time>2025-07-01T08:00:00-04:00</In_Time>
            <Out_Time>2025-07-01T12:00:00-04:00</Out_Time>
            <Hours>-2</Hours>
            <Type>PTO</Type>
        </Details>
    </Entry>
    <Entry>
        <ID>2</ID>
        <Name>Scott</Name>
        <Title>Vice President</Title>
        <Details>
            <Date>2025-07-03-07:00</Date>
            <Hours>8</Hours>
            <Type>Holiday</Type>
        </Details>
        <Details>
            <Date>2025-07-07-07:00</Date>
            <Hours>8</Hours>
            <Type>Holiday</Type>
        </Details>
        <Details>
            <Date>2025-07-08-07:00</Date>
            <Hours>8</Hours>
            <Type>PTO</Type>
        </Details>
    </Entry>
</Data>

解决方案XSLT代码

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" encoding="UTF-8"/>

    <!-- 按员工ID分组 -->
    <xsl:for-each-group select="/Data/Entry" group-by="ID">
        <!-- 在员工组内按日期分组 -->
        <xsl:for-each-group select="current-group()/Details" group-by="Date">
            <xsl:value-of select="ancestor::Entry/Name"/>
            <xsl:text>,</xsl:text>
            <xsl:value-of select="ancestor::Entry/Title"/>
            <xsl:text>,</xsl:text>
            <xsl:value-of select="current-grouping-key()"/>
            <xsl:text>,</xsl:text>
            <!-- 取当日最后一条记录的In_Time -->
            <xsl:value-of select="current-group()[last()]/In_Time"/>
            <xsl:text>,</xsl:text>
            <!-- 取当日最后一条记录的Out_Time -->
            <xsl:value-of select="current-group()[last()]/Out_Time"/>
            <xsl:text>,</xsl:text>
            <!-- 计算当日Hours总和 -->
            <xsl:value-of select="sum(current-group()/Hours)"/>
            <xsl:text>&#10;</xsl:text>
        </xsl:for-each-group>
    </xsl:for-each-group>
</xsl:stylesheet>

实现思路

  1. 利用XSLT 2.0的分组功能,先按Entry/ID分组,确保同一员工的记录归为一组;
  2. 在每个员工组内,再按Details/Date分组,聚合同一日期的所有详情记录;
  3. 对每个日期组:
    • 提取员工姓名和职位信息;
    • 输出分组日期;
    • 取该组最后一条记录的In_Time和Out_Time(无对应节点则自动留空);
    • 使用sum()函数计算当日所有Hours的总和;
  4. 输出格式为CSV,用逗号分隔字段,换行符分隔每条记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 18:53:14