求助:使用XSLT 1.0按sku值分组XML并汇总quantity
XSLT 1.0 按SKU分组汇总数量解决方案
针对你需要按<sku>子元素值分组并汇总对应<quantity>的需求,在XSLT 1.0中我们可以用Muenchian分组来实现——这是XSLT 1.0里最成熟高效的分组方案。
先修正输入XML的标签错误
你的输入XML里存在标签不匹配问题:<E1>abc</merchantcode>应该改成<E1>abc</E1>,否则XML无法正常解析。修正后的输入XML如下:
<body> <Root1> <Root2> <E1>abc</E1> <C1> <order> <catalog> <catalogitem>100</catalogitem> <sku>100</sku> <quantity>1</quantity> </catalog> </order> </C1> <C1> <order> <catalog> <catalogitem>100</catalogitem> <sku>100</sku> <quantity>2</quantity> </catalog> </order> </C1> <C1> <order> <catalog> <catalogitem>111</catalogitem> <sku>111</sku> <quantity>1</quantity> </catalog> </order> </C1> </Root2> </Root1> </body>
实现分组汇总的XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 定义分组键:按sku的值对catalog元素分组 --> <xsl:key name="sku-group" match="catalog" use="sku"/> <!-- 身份模板:默认复制所有节点和属性,保留原XML大部分结构 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 重写Root2节点的处理逻辑,实现分组汇总 --> <xsl:template match="Root2"> <xsl:copy> <!-- 保留原有的E1节点 --> <xsl:apply-templates select="E1"/> <!-- 只处理每个sku分组中的第一个catalog节点 --> <xsl:for-each select="C1/order/catalog[generate-id() = generate-id(key('sku-group', sku)[1])]"> <C1> <order> <catalog> <!-- 复制当前分组的catalogitem和sku --> <xsl:apply-templates select="catalogitem|sku"/> <!-- 汇总当前sku对应的所有quantity数值 --> <quantity> <xsl:value-of select="sum(key('sku-group', sku)/quantity)"/> </quantity> </catalog> </order> </C1> </xsl:for-each> </xsl:copy> </xsl:template> </xsl:stylesheet>
关键逻辑说明
- Muenchian分组核心:通过
<xsl:key>定义以<sku>值为标识的分组规则,把所有相同sku的<catalog>元素归为一组。 - 身份模板:确保原XML中不需要修改的节点(比如
<body>、<Root1>)都原样复制,避免破坏原有结构。 - 分组处理:在
<Root2>的模板中,只筛选每个sku分组的第一个<catalog>节点作为代表,复制它的<catalogitem>和<sku>,再用sum()函数计算该分组下所有<quantity>的总和。 - 结构一致性:生成的结果会完全保留原有的
<C1>、<order>层级,只修改分组后的数量值。
最终输出XML
<body> <Root1> <Root2> <E1>abc</E1> <C1> <order> <catalog> <catalogitem>100</catalogitem> <sku>100</sku> <quantity>3</quantity> </catalog> </order> </C1> <C1> <order> <catalog> <catalogitem>111</catalogitem> <sku>111</sku> <quantity>1</quantity> </catalog> </order> </C1> </Root2> </Root1> </body>
内容的提问来源于stack exchange,提问作者Lakshmi Kiran
相关产品推荐
相关产品推荐

