如何用XSLT移除存在重复兄弟节点的XML节点?
XSLT移除重复文本的兄弟节点(含原节点与重复节点)
示例输入XML
假设你的XML结构如下(包含重复的Africa、Mexico节点):
<root> <row>Africa</row> <row>Africa</row> <row>Canada</row> <row>Mexico</row> <row>Mexico</row> <row>Brazil</row> </root>
目标输出XML
仅保留无重复的
<root> <row>Canada</row> <row>Brazil</row> </root>
XSLT实现方案
方案1:XSLT 1.0(兼容旧版处理器)
利用Muenchian分组实现,核心是按
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- 按<row>的文本内容建立索引键 --> <xsl:key name="row-text-group" match="row" use="normalize-space(text())"/> <xsl:template match="root"> <xsl:copy> <!-- 筛选:当前节点是分组首节点,且分组内仅一个节点 --> <xsl:copy-of select="row[ generate-id() = generate-id(key('row-text-group', normalize-space(text()))[1]) and count(key('row-text-group', normalize-space(text()))) = 1 ]"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
方案2:XSLT 2.0及以上(更简洁)
利用原生分组语法,代码可读性更强:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="root"> <xsl:copy> <!-- 按<row>文本分组,仅保留大小为1的分组 --> <xsl:for-each-group select="row" group-by="normalize-space(text())"> <xsl:if test="current-group()[last()] = current-group()[1]"> <xsl:copy-of select="current-group()"/> </xsl:if> </xsl:for-each-group> </xsl:copy> </xsl:template> </xsl:stylesheet>
关键逻辑说明
- 使用
normalize-space(text())是为了忽略文本前后的空白,避免因空白差异误判为非重复;如果你的文本是严格无空白的,也可以直接用
text()。 - 核心思路是分组后过滤:将所有
按文本内容分组,仅保留那些分组内只有一个节点的组——这样就同时移除了原重复节点和它的副本,只留下完全唯一的
。
内容的提问来源于stack exchange,提问作者Hanu575
相关产品推荐
相关产品推荐

