XSLT按子节点分组:XML按账单号分组转换需求
按账单号分组转换XML的解决方案
嘿,我懂你想把这些<item>节点按<bill>的账单号分组的需求!这种场景用XSLT来处理是最直接高效的,我给你准备了一套可以直接复用的方案👇
原始简化XML结构
<items> <item> <bill>10</bill> <name>first (10)</name> <price>111</price> </item> <item> <bill>10</bill> <name>second (10)</name> <price>222</price> </item> <item> <bill>10</bill> <name>third (10)</name> <price>333</price> </item> <!-- 这里可以有其他不同bill号的item --> </items>
XSLT转换代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 定义分组的key,以bill节点的文本值为键 --> <xsl:key name="bill-group" match="item" use="bill"/> <xsl:template match="/items"> <!-- 根节点输出为grouped-bills --> <grouped-bills> <!-- 遍历所有唯一的bill分组,用generate-id确保只处理每个组一次 --> <xsl:for-each select="item[generate-id() = generate-id(key('bill-group', bill)[1])]"> <!-- 生成每个账单组的节点 --> <bill-group bill-number="{bill}"> <!-- 输出当前账单下的所有item子节点 --> <xsl:copy-of select="key('bill-group', bill)"/> </bill-group> </xsl:for-each> </grouped-bills> </xsl:template> </xsl:stylesheet>
转换后的结果
运行上面的XSLT后,你会得到按账单号分组后的XML:
<grouped-bills> <bill-group bill-number="10"> <item> <bill>10</bill> <name>first (10)</name> <price>111</price> </item> <item> <bill>10</bill> <name>second (10)</name> <price>222</price> </item> <item> <bill>10</bill> <name>third (10)</name> <price>333</price> </item> </bill-group> <!-- 如果有其他bill号的item,会在这里生成对应的bill-group节点 --> </grouped-bills>
关键部分说明
<xsl:key>:用来定义分组规则,把所有item节点按bill的文本值归类,相当于给每个账单号创建一个专属“集合”generate-id() = generate-id(key('bill-group', bill)[1]):这个条件是核心,用来筛选出每个账单组的第一个item节点,确保同一个账单组只会被处理一次,避免重复生成分组<xsl:copy-of>:直接复制当前账单组下的所有item节点,完整保留原始的字段结构;如果需要重组字段,把这个换成<xsl:for-each>遍历每个item再自定义输出即可
内容的提问来源于stack exchange,提问作者FastJoe
相关产品推荐
相关产品推荐

