XSLT按节点分组问题:如何避免同ID节点内容合并到同一行
XSLT分组后表格行合并问题的排查与解决
你这问题大概率是分组后的节点选取逻辑有误,不是非得依赖变量(合理用变量能优化代码,但核心问题出在select/条件设置上)。
常见的问题点和修正方向如下:
1. Muenchian分组的键匹配或分组选取写错了
如果你用的是Muenchian分组(靠<xsl:key>定义分组规则),先查两处:
- 键的定义:比如
<xsl:key name="group-by-id" match="你的节点名" use="@id"/>,确保use指向的是正确的ID属性或节点值,别写错路径。 - 分组筛选条件:必须用
generate-id() = generate-id(key('group-by-id', @id)[1])来选每组的第一个节点,要是直接遍历所有节点,肯定会重复输出或者合并内容。
2. 表格行输出时错误遍历了同组所有节点
如果输出表格行的时候,你直接把同ID的所有节点值一次性输出,自然会合并到同一单元格。正确的做法是:
- 先拿每组的第一个节点当“代表”,每一个代表输出一行表格
- 要是需要在这行里展示同组的所有内容,就在行里面嵌套遍历同组的节点,每个内容单独做单元格
举个实际修正例子
假设你的XML结构是:
<data> <entry id="001">产品A</entry> <entry id="001">规格X</entry> <entry id="002">产品B</entry> </data>
错误的XSL写法(导致内容合并):
<xsl:for-each select="entry"> <tr> <td><xsl:value-of select="key('group-by-id', @id)"/></td> </tr> </xsl:for-each>
修正后的XSL(每组一行,行内拆分同组内容为单元格):
<xsl:key name="group-by-id" match="entry" use="@id"/> <xsl:template match="/"> <table> <!-- 只遍历每组的第一个节点,生成表格行 --> <xsl:for-each select="data/entry[generate-id() = generate-id(key('group-by-id', @id)[1])]"> <tr> <td>ID: <xsl:value-of select="@id"/></td> <!-- 遍历同组所有节点,生成对应单元格 --> <xsl:for-each select="key('group-by-id', @id)"> <td><xsl:value-of select="."/></td> </xsl:for-each> </tr> </xsl:for-each> </table> </xsl:template>
总结
先重点检查这两处:
- 分组筛选的条件是不是只选了每组的第一个节点
- 表格行内是不是错误地把同组所有节点的值一次性输出,而非逐个遍历生成单元格
内容的提问来源于stack exchange,提问作者MPourier
相关产品推荐
相关产品推荐

