XSLT分组求和问题:按Type分组计算同类型GrossPay总和
按薪资类型分组并计算GrossPay总和的XSLT实现
这里是处理你的XML薪资数据的解决方案,我们会用XSLT的经典分组方案(Muenchian分组,适配XSLT 1.0)来按Type字段分组,计算每组的GrossPay总和,输出符合你要求的文本格式。
原始XML数据
<Payroll_Data> <EmpId>1000</EmpId> <FirstName>Mark</FirstName> <LastName>Henry</LastName> <Salary> <Type>B</Type> <GrossPay>1000.50</GrossPay> </Salary> <Salary> <Type>B</Type> <GrossPay>847.50</GrossPay> </Salary> <Salary> <Type>X</Type> <GrossPay>820</GrossPay> </Salary> </Payroll_Data> <Payroll_Data> <EmpId>1001</EmpId> <FirstName>John</FirstName> <LastName>Diggle</LastName> <Salary> <Type>B</Type> <GrossPay>800.98</GrossPay> </Salary> <Salary> <Type>X</Type> <GrossPay>630.50</GrossPay> </Salary> <Salary> <Type>X</Type> <GrossPay>600.50</GrossPay> </Salary> </Payroll_Data>
预期输出格式
EmpId FirstName LastName Type GrossPay Sum of Grosspay by Type 1000 Mark Henry B 1000.50 1847.99 1000 Mark Henry B 847.49 1847.99 1000 Mark Henry X 820 820 1001 John Diggle B 800.98 800.98 1001 John Diggle X 630.50 1231 1001 John Diggle X 600.50 1231
(注:你提供的预期结果最后一行缺失了总和,这里按逻辑补充完整)
XSLT解决方案
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8" indent="no"/> <!-- 定义分组键:按员工ID+薪资类型组合,避免不同员工同类型薪资混组 --> <xsl:key name="salaryByEmpType" match="Salary" use="concat(../EmpId, '|', Type)"/> <xsl:template match="/"> <!-- 输出表头 --> <xsl:text>EmpId FirstName LastName Type GrossPay Sum of Grosspay by Type
</xsl:text> <!-- 遍历每个员工的薪资数据 --> <xsl:for-each select="Payroll_Data"> <xsl:variable name="empId" select="EmpId"/> <xsl:variable name="firstName" select="FirstName"/> <xsl:variable name="lastName" select="LastName"/> <!-- 遍历当前员工的每一笔薪资 --> <xsl:for-each select="Salary"> <xsl:variable name="currentType" select="Type"/> <!-- 计算当前员工同类型薪资的总和 --> <xsl:variable name="groupSum" select="sum(key('salaryByEmpType', concat($empId, '|', $currentType))/GrossPay)"/> <!-- 格式化输出当前行 --> <xsl:value-of select="$empId"/> <xsl:text> </xsl:text> <xsl:value-of select="$firstName"/> <xsl:text> </xsl:text> <xsl:value-of select="$lastName"/> <xsl:text> </xsl:text> <xsl:value-of select="$currentType"/> <xsl:text> </xsl:text> <xsl:value-of select="format-number(GrossPay, '0.00')"/> <xsl:text> </xsl:text> <xsl:value-of select="format-number($groupSum, '0.00')"/> <xsl:text>
</xsl:text> </xsl:for-each> </xsl:for-each> </xsl:template> </xsl:stylesheet>
代码说明
- 分组逻辑:用
concat(../EmpId, '|', Type)作为分组键,确保是按每个员工的薪资类型独立分组,不会把不同员工的同类型薪资混在一起计算总和。 - 总和计算:通过
sum(key('salaryByEmpType', concat($empId, '|', $currentType))/GrossPay)快速获取当前分组的GrossPay总和。 - 格式适配:用
format-number保证数值保留两位小数,
实现换行,完全匹配你要的文本输出格式。
内容的提问来源于stack exchange,提问作者ar1991
相关产品推荐
相关产品推荐

