基于XSLT 1.0实现按Item ID排序并汇总库存总量的需求咨询
嗨,关于XSLT 1.0里按Item ID排序并汇总库存总量的需求,我给你梳理下可行的实现思路,其实这俩需求可以结合起来高效搞定,咱们一步步拆解:
一、核心方法:Muenchian分组 + 排序
XSLT 1.0没有原生的分组功能,所以业界常用Muenchian分组法来实现按唯一值分组汇总,同时我们可以在分组遍历的环节直接加上排序,一次性完成两个目标。
步骤1:定义分组Key
首先要通过<xsl:key>定义一个以Item ID为标识的分组键,这样能快速找到所有相同Item ID的节点:
<xsl:key name="item-group" match="Item" use="@ItemID"/>
这里的match要对应你输入XML里的库存项节点(比如<Item>),use指定分组依据的Item ID属性(如果Item ID是子元素而不是属性,就改成use="ItemID")。
步骤2:遍历唯一分组并排序
接下来,我们需要筛选出每个Item ID分组的第一个节点(代表这个唯一分组),然后对这些节点按Item ID排序,同时汇总该分组下的所有库存:
<xsl:for-each select="Inventory/Item[generate-id() = generate-id(key('item-group', @ItemID)[1])]"> <!-- 按Item ID升序排序,如需降序改成order="descending" --> <xsl:sort select="@ItemID" data-type="text" order="ascending"/> <!-- 生成汇总结果 --> <SummaryItem> <ItemID><xsl:value-of select="@ItemID"/></ItemID> <TotalStock> <!-- 用sum函数汇总当前分组下所有Stock值 --> <xsl:value-of select="sum(key('item-group', @ItemID)/@Stock)"/> </TotalStock> </SummaryItem> </xsl:for-each>
这里的generate-id()是XSLT 1.0的内置函数,用来生成节点的唯一标识。只有每个分组的第一个节点会满足generate-id() = generate-id(key('item-group', @ItemID)[1]),这样就筛选出了所有唯一的Item ID分组。
完整示例代码
给你一个完整的可运行示例,假设你的输入XML结构是这样的:
<Inventory> <Item ItemID="B002" Stock="15"/> <Item ItemID="A001" Stock="20"/> <Item ItemID="C003" Stock="8"/> <Item ItemID="B002" Stock="5"/> </Inventory>
对应的XSLT代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- 定义分组Key --> <xsl:key name="item-group" match="Item" use="@ItemID"/> <xsl:template match="/"> <InventorySummary> <!-- 遍历唯一分组并排序 --> <xsl:for-each select="Inventory/Item[generate-id() = generate-id(key('item-group', @ItemID)[1])]"> <xsl:sort select="@ItemID" order="ascending"/> <SummaryItem> <ItemID><xsl:value-of select="@ItemID"/></ItemID> <TotalStock> <xsl:value-of select="sum(key('item-group', @ItemID)/@Stock)"/> </TotalStock> </SummaryItem> </xsl:for-each> </InventorySummary> </xsl:template> </xsl:stylesheet>
运行后输出的XML会是按Item ID排序且汇总后的结果:
<InventorySummary> <SummaryItem> <ItemID>A001</ItemID> <TotalStock>20</TotalStock> </SummaryItem> <SummaryItem> <ItemID>B002</ItemID> <TotalStock>20</TotalStock> </SummaryItem> <SummaryItem> <ItemID>C003</ItemID> <TotalStock>8</TotalStock> </SummaryItem> </InventorySummary>
注意事项
- 如果你的Item ID或Stock是子元素(比如
<Item><ID>A001</ID><Stock>20</Stock></Item>),记得把代码里的@ItemID改成ID,@Stock改成Stock。 - 如果需要按数字排序Item ID(比如ID是纯数字),可以在
<xsl:sort>里加上data-type="number",避免文本排序导致的顺序问题。
内容的提问来源于stack exchange,提问作者Pavel Košek
相关产品推荐
相关产品推荐

