如何在XSLT中实现多分组?附XML数据与解决方案
XSLT多维度分组实现:按MemberID、DepositDate、DepositType汇总金额
问题场景
需要对存款XML数据按 MemberID(成员ID)→ DepositDate(存款日期)→ DepositType(存款类型) 三级分组,同时汇总每组的总存款金额。
示例输入XML
<Deposits> <Deposit> <MemberID>101</MemberID> <DepositDate>2024-05-01</DepositDate> <DepositType>Savings</DepositType> <Amount>500</Amount> </Deposit> <Deposit> <MemberID>101</MemberID> <DepositDate>2024-05-01</DepositDate> <DepositType>Savings</DepositType> <Amount>300</Amount> </Deposit> <Deposit> <MemberID>101</MemberID> <DepositDate>2024-05-02</DepositDate> <DepositType>Checking</DepositType> <Amount>1000</Amount> </Deposit> <Deposit> <MemberID>102</MemberID> <DepositDate>2024-05-01</DepositDate> <DepositType>Savings</DepositType> <Amount>750</Amount> </Deposit> </Deposits>
错误的初始XSLT(仅按日期和类型分组,遗漏成员ID)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <GroupedDeposits> <xsl:for-each-group select="Deposits/Deposit" group-by="concat(DepositDate, '|', DepositType)"> <Group> <DepositDate><xsl:value-of select="current-grouping-key()"/></DepositDate> <TotalAmount><xsl:value-of select="sum(current-group()/Amount)"/></TotalAmount> </Group> </xsl:for-each-group> </GroupedDeposits> </xsl:template> </xsl:stylesheet>
错误结果:不同成员的同日期同类型存款被合并,无法区分成员维度,汇总金额不准确。
修订后的正确XSLT(三级分组)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <GroupedDeposits> <!-- 第一级:按MemberID分组 --> <xsl:for-each-group select="Deposits/Deposit" group-by="MemberID"> <MemberGroup> <MemberID><xsl:value-of select="current-grouping-key()"/></MemberID> <!-- 第二级:在成员组内按DepositDate分组 --> <xsl:for-each-group select="current-group()" group-by="DepositDate"> <DateGroup> <DepositDate><xsl:value-of select="current-grouping-key()"/></DepositDate> <!-- 第三级:在日期组内按DepositType分组 --> <xsl:for-each-group select="current-group()" group-by="DepositType"> <TypeGroup> <DepositType><xsl:value-of select="current-grouping-key()"/></DepositType> <TotalAmount><xsl:value-of select="sum(current-group()/Amount)"/></TotalAmount> </TypeGroup> </xsl:for-each-group> </DateGroup> </xsl:for-each-group> </MemberGroup> </xsl:for-each-group> </GroupedDeposits> </xsl:template> </xsl:stylesheet>
关键逻辑说明
- 三级嵌套分组:通过嵌套
<xsl:for-each-group>实现从成员到日期再到类型的层级分组,确保每个维度的独立性。 current-group()的使用:每一层分组中,current-group()指代当前分组下的所有节点,用于后续子分组或汇总计算。- 金额汇总:使用
sum(current-group()/Amount)计算当前分组的总金额,确保数据准确。
正确输出结果
<GroupedDeposits> <MemberGroup> <MemberID>101</MemberID> <DateGroup> <DepositDate>2024-05-01</DepositDate> <TypeGroup> <DepositType>Savings</DepositType> <TotalAmount>800</TotalAmount> </TypeGroup> </DateGroup> <DateGroup> <DepositDate>2024-05-02</DepositDate> <TypeGroup> <DepositType>Checking</DepositType> <TotalAmount>1000</TotalAmount> </TypeGroup> </DateGroup> </MemberGroup> <MemberGroup> <MemberID>102</MemberID> <DateGroup> <DepositDate>2024-05-01</DepositDate> <TypeGroup> <DepositType>Savings</DepositType> <TotalAmount>750</TotalAmount> </TypeGroup> </DateGroup> </MemberGroup> </GroupedDeposits>
内容的提问来源于stack exchange,提问作者Wasupbi
相关产品推荐
相关产品推荐

