按容器类型汇总数量:XSLT 1.0实现需求及代码问题排查
问题描述
现有XML数据:
<?xml version="1.0" encoding="UTF-8"?> <Containers> <ContainerGroup Type="40HC" Quantity="1"/> <ContainerGroup Type="40HC" Quantity="3"/> <ContainerGroup Type="42PL" Quantity="4"/> <ContainerGroup Type="40HC" Quantity="2"/> </Containers>
需要编写XSLT 1.0代码,生成如下结果:
<Sum>40HC-6||42PL-4</Sum>
用户尝试的第一段代码未生效:
<xsl:for-each select="Containers/ContainerGroup/@Type"> <xsl:variable name="sumQuantity" select="sum(@Quantity)" /> <xsl:if test="position() != 1">||</xsl:if> <xsl:value-of select="concat(@Type,'-',$sumQuantity)"/> </xsl:for-each>
编辑1:使用Muenchian方法编写的代码仍未生效:
<xsl:key name="container-by-type" match="Containers/ContainerGroup" use="Containers/ContainerGroup/@Type"/> <xsl:template name="sumQuantity"> <xsl:for-each select="//Containers/ContainerGroup[generate-id() = generate-id(key('container-by-type', Containers/ContainerGroup/@Type)[1])]"> <xsl:variable name="grp" select="key('container-by-type', Containers/ContainerGroup/@Type)" /> <xsl:if test="position() != 1">||</xsl:if> <xsl:value-of select="concat(Containers/ContainerGroup/@Type,'-',sum($grp/@Quantity))"/> </xsl:for-each> </xsl:template>
错误原因分析
- 第一段代码问题:
xsl:for-each选择的是@Type属性节点,此时上下文为属性节点,无法直接获取@Quantity(属性节点无下属属性),导致sum(@Quantity)结果为0;同时会遍历所有Type属性,重复输出同类型条目。 - Muenchian方法代码问题:键的
use属性写法错误,当前上下文已是ContainerGroup节点,无需写完整路径Containers/ContainerGroup/@Type,直接写@Type即可;for-each的匹配条件和变量grp的选择也重复了无效路径。
正确的XSLT 1.0代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- Muenchian分组键:按ContainerGroup的Type属性分组 --> <xsl:key name="container-type" match="ContainerGroup" use="@Type"/> <xsl:template match="/"> <Sum> <!-- 遍历每个分组的第一个节点,确保每种类型只处理一次 --> <xsl:for-each select="Containers/ContainerGroup[generate-id() = generate-id(key('container-type', @Type)[1])]"> <!-- 非第一个分组前添加分隔符 --> <xsl:if test="position() > 1">||</xsl:if> <!-- 拼接类型与对应数量总和 --> <xsl:value-of select="concat(@Type, '-', sum(key('container-type', @Type)/@Quantity))"/> </xsl:for-each> </Sum> </xsl:template> </xsl:stylesheet>
代码说明
- 定义
container-type键,以ContainerGroup的@Type属性作为分组依据 - 在根模板中,通过
generate-id()筛选每个分组的首个节点,避免重复处理同类型条目 - 对每个分组,计算该类型下所有
Quantity属性的总和,拼接成类型-总和格式,并在非首个分组前添加||分隔符
内容的提问来源于stack exchange,提问作者Prateek
相关产品推荐
相关产品推荐

