XML元素分组与汇总

在处理XML数据时,经常需要对元素进行分组和汇总。例如,可能需要根据团队ID将员工的工作时间进行汇总。本文将介绍如何使用XSLT技术实现这一目标。

首先,来看一个XML示例,其中包含了员工的详细信息,包括团队ID、任务ID、工作时间、员工ID、姓名和姓氏。

<?xml version="1.0"?> <Employees> <Employee> <TeamID>1</TeamID> <TeamName>Sales</TeamName> <TaskID>1</TaskID> <Hours>5</Hours> <EmployeeID>1</EmployeeID> <Name>Bob</Name> <Surname>Shibob</Surname> </Employee> ... </Employees>

如果想要按团队ID对员工的工作时间进行汇总,一种方法是遍历每个<Employee>元素,但这种方法效率低下,因为它需要跟踪前一个元素的ID。

更高效的方法是使用Muenchian方法,即通过构建一个唯一键的列表,然后使用这些键来分组结果。首先,需要定义用于分组<Employee>元素的键,包括团队ID和员工ID。

<xsl:key name="keyTeamID" match="Employee" use="TeamID"/> <xsl:key name="keyEmployeeID" match="Employee" use="EmployeeID"/>

接下来,选择每个团队的第一个元素,并将该团队的所有<Employee>元素保存到一个变量中。

<xsl:for-each select="//Employee[generate-id(.) = generate-id(key('keyTeamID', TeamID)[1])]"> <xsl:variable name="lngTeamID"> <xsl:value-of select="TeamID"/> </xsl:variable> <xsl:variable name="lstEmployee" select="//Employee[TeamID=$lngTeamID]"/>

现在,需要将这个列表中的<Employee>元素按员工ID进行分组。这与按团队ID分组类似,不同之处在于,这次只需要从变量中选择元素,而不需要从整个结果集中选择元素。

<xsl:for-each select="$lstEmployee[generate-id(.) = generate-id(key('keyEmployeeID', EmployeeID)[1])]">

最后,可以轻松地显示每个员工的总工作时间。

<xsl:value-of select="sum($lstEmployee[EmployeeID=$lngEmployeeID]/Hours)"/> <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:key name="keyTeamID" match="Employee" use="TeamID"/> <xsl:key name="keyEmployeeID" match="Employee" use="EmployeeID"/> <xsl:template match="/"> <html> <head> <title>Employee Hours By Team</title> <link type="text/css" rel="stylesheet" href="groupxml.css"/> </head> <body> <h3>Employee Hours By Team</h3> <table> <xsl:for-each select="//Employee[generate-id(.) = generate-id(key('keyTeamID', TeamID)[1])]"> <xsl:variable name="lngTeamID"> <xsl:value-of select="TeamID"/> </xsl:variable> <xsl:variable name="lstEmployee" select="//Employee[TeamID=$lngTeamID]"/> <xsl:call-template name="ShowEmployeesInTeam"> <xsl:with-param name="lstEmployee" select="$lstEmployee"/> </xsl:call-template> </xsl:for-each> <tr> <td colspan="4" class="RightJustified DarkBack">Grand Total</td> <td colspan="1" class="RightJustified DarkBack"> <xsl:value-of select="sum(//Employee/Hours)"/> </td> </tr> </table> </body> </html> </xsl:template> <xsl:template name="ShowEmployeesInTeam"> <xsl:param name="lstEmployee"/> <tr> <td colspan="4" class="DarkBack"> <xsl:value-of select="$lstEmployee[1]/TeamName"/> </td> <td colspan="1" class="DarkBack RightJustified">HOURS</td> </tr> <xsl:for-each select="$lstEmployee[generate-id(.) = generate-id(key('keyEmployeeID', EmployeeID)[1])]"> <xsl:variable name="lngEmployeeID" select="EmployeeID"/> <tr> <td colspan="4"> <xsl:value-of select="$lstEmployee[EmployeeID=$lngEmployeeID]/Name"/> <xsl:value-of select="$lstEmployee[EmployeeID=$lngEmployeeID]/Surname"/> </td> <td colspan="1" class="RightJustified"> <xsl:value-of select="sum($lstEmployee[EmployeeID=$lngEmployeeID]/Hours)"/> </td> </tr> </xsl:for-each> <tr> <td colspan="4" class="LightBack RightJustified">Sub-Total</td> <td colspan="1" class="LightBack RightJustified"> <xsl:value-of select="sum($lstEmployee/Hours)"/> </td> </tr> </xsl:template> </xsl:stylesheet>
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485