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

XSLT 2.0按empID与Date分组求和结果异常求助

XSLT分组求和错误修正

源XML数据

<?xml version="1.0" encoding="UTF-8"?>
<Workers>
    <Worker>
        <empID>12354</empID>
        <Cost>
            <Date>2023-10-06-07:00</Date>
            <Type>Expense</Type>
            <Amount>108</Amount>
        </Cost>
        <Cost>
            <Date>2023-10-06-07:00</Date>
            <Type>Bonus</Type>
            <Amount>200</Amount>
        </Cost>
        <Cost>
            <Date>2023-10-06-07:00</Date>
            <Type>Expense</Type>
            <Amount>550</Amount>
        </Cost>
        <Cost>
            <Date>2023-10-10-07:00</Date>
            <Type>Expense</Type>
            <Amount>100</Amount>
        </Cost>
        <Cost>
            <Date>2023-10-10-07:00</Date>
            <Type>Bonus</Type>
            <Amount>200</Amount>
        </Cost>
        <Cost>
            <Date>2023-10-10-07:00</Date>
            <Type>Expense</Type>
            <Amount>120</Amount>
        </Cost>
        <Cost>
            <Date>2023-10-11-07:00</Date>
            <Type>Expense</Type>
            <Amount>120</Amount>
        </Cost>
    </Worker>
    <Worker>
        <empID>4567</empID>
        <Cost>
            <Date>2023-10-06-07:00</Date>
            <Type>Expense</Type>
            <Amount>90</Amount>
        </Cost>
        <Cost>
            <Date>2023-10-06-07:00</Date>
            <Type>Bonus</Type>
            <Amount>10</Amount>
        </Cost>
        <Cost>
            <Date>2023-10-06-07:00</Date>
            <Type>Expense</Type>
            <Amount>120</Amount>
        </Cost>
        <Cost>
            <Date>2023-10-10-07:00</Date>
            <Type>Expense</Type>
            <Amount>1297</Amount>
        </Cost>
        <Cost>
            <Date>2023-10-10-07:00</Date>
            <Type>Bonus</Type>
            <Amount>312</Amount>
        </Cost>
    </Worker>
</Workers>

预期需求与输出

  • 按<empID>和<Date>分组记录;
  • 每个唯一<Date>对应生成一个<Worker>节点:empID为12354的员工有3个唯一Date,需生成3个<Worker>;empID为4567的员工有2个唯一Date,需生成2个<Worker>;
  • 对每个唯一<Date>,分别求和Type为Expense和Bonus的金额。

预期输出XML:

<?xml version="1.0" encoding="UTF-8"?>
<Workers>
    <Worker>
        <UniqueID>12354</UniqueID>
        <Date>2023-10-06-07:00</Date>
        <ExpenseAmount>658.00</ExpenseAmount>
        <BonusAmount>200.00</BonusAmount>
    </Worker>
    <Worker>
        <UniqueID>12354</UniqueID>
        <Date>2023-10-10-07:00</Date>
        <ExpenseAmount>220.00</ExpenseAmount>
        <BonusAmount>200.00</BonusAmount>
    </Worker>
    <Worker>
        <UniqueID>12354</UniqueID>
        <Date>2023-10-11-07:00</Date>
        <ExpenseAmount>120.00</ExpenseAmount>
        <BonusAmount>0.00</BonusAmount>
    </Worker>
    <Worker>
        <UniqueID>4567</UniqueID>
        <Date>2023-10-06-07:00</Date>
        <ExpenseAmount>210.00</ExpenseAmount>
        <BonusAmount>10.00</BonusAmount>
    </Worker>
    <Worker>
        <UniqueID>4567</UniqueID>
        <Date>2023-10-10-07:00</Date>
        <ExpenseAmount>1297.00</ExpenseAmount>
        <BonusAmount>312.00</BonusAmount>
    </Worker>
</Workers>

注:原预期输出中第三个Worker的金额标注存在笔误,此处已修正为正确值

当前编写的XSLT代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="Workers">
        <Workers>
            <xsl:for-each-group select="Worker" group-by="empID">
                <xsl:for-each-group select="current-group()" group-by="Cost/Date">
                    <Worker>
                        <UniqueID>
                            <xsl:value-of select="empID"/>
                        </UniqueID>
                        <Date>
                            <xsl:value-of select="current-grouping-key()"/>
                        </Date>
                        <ExpenseAmount>
                            <xsl:value-of
                                select="format-number(sum(current-group()/Cost[Type = 'Expense']/Amount), '#.00')"/>
                        </ExpenseAmount>
                        <BonusAmount>
                            <xsl:value-of select="format-number(sum(current-group()/Cost[Type = 'Bonus']/Amount), '#.00')"/>
                        </BonusAmount>
                    </Worker>
                </xsl:for-each-group>
            </xsl:for-each-group>
        </Workers>
    </xsl:template>
</xsl:stylesheet>

当前输出结果

<?xml version="1.0" encoding="UTF-8"?>
<Workers>
   <Worker>
      <UniqueID>12354</UniqueID>
      <Date>2023-10-06-07:00</Date>
      <ExpenseAmount>998.00</ExpenseAmount>
      <BonusAmount>400.00</BonusAmount>
   </Worker>
   <Worker>
      <UniqueID>12354</UniqueID>
      <Date>2023-10-10-07:00</Date>
      <ExpenseAmount>998.00</ExpenseAmount>
      <BonusAmount>400.00</BonusAmount>
   </Worker>
   <Worker>
      <UniqueID>12354</UniqueID>
      <Date>2023-10-11-07:00</Date>
      <ExpenseAmount>998.00</ExpenseAmount>
      <BonusAmount>400.00</BonusAmount>
   </Worker>
   <Worker>
      <UniqueID>4567</UniqueID>
      <Date>2023-10-06-07:00</Date>
      <ExpenseAmount>1507.00</ExpenseAmount>
      <BonusAmount>322.00</BonusAmount>
   </Worker>
   <Worker>
      <UniqueID>4567</UniqueID>
      <Date>2023-10-10-07:00</Date>
      <ExpenseAmount>1507.00</ExpenseAmount>
      <BonusAmount>322.00</BonusAmount>
   </Worker>
</Workers>

问题原因与修正方案

错误原因

原代码第二层分组对象是current-group()(即整个<Worker>节点),而非该员工下的<Cost>节点。这导致分组后current-group()仍包含该员工所有日期的<Cost>记录,求和时会累加该员工所有日期的金额,而非当前分组日期的金额。

修正后的XSLT代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="Workers">
        <Workers>
            <!-- 按empID分组 -->
            <xsl:for-each-group select="Worker" group-by="empID">
                <!-- 对当前员工的所有Cost节点按Date分组 -->
                <xsl:for-each-group select="current-group()/Cost" group-by="Date">
                    <Worker>
                        <UniqueID>
                            <xsl:value-of select="../empID"/>
                        </UniqueID>
                        <Date>
                            <xsl:value-of select="current-grouping-key()"/>
                        </Date>
                        <ExpenseAmount>
                            <xsl:value-of select="format-number(sum(current-group()[Type='Expense']/Amount), '#.00')"/>
                        </ExpenseAmount>
                        <BonusAmount>
                            <xsl:value-of select="format-number(sum(current-group()[Type='Bonus']/Amount), '#.00')"/>
                        </BonusAmount>
                    </Worker>
                </xsl:for-each-group>
            </xsl:for-each-group>
        </Workers>
    </xsl:template>
</xsl:stylesheet>

修正说明

  1. 第二层分组对象改为current-group()/Cost,即当前员工下的所有<Cost>节点,按<Date>分组;
  2. 求和时直接对current-group()(当前日期的所有<Cost>)中对应Type的<Amount>求和;
  3. <UniqueID>通过../empID获取当前Cost所属员工的ID,确保关联正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:05:54