首页
学习
活动
专区
圈层
工具
发布

XSLT :如何删除XML中的重复标记

XSLT 删除 XML 中的重复标记

基础概念

XSLT (Extensible Stylesheet Language Transformations) 是一种用于将 XML 文档转换为其他格式的语言。在处理 XML 数据时,我们经常需要去除重复的元素或节点。

解决方案

方法一:使用 Muenchian 分组法(最常用)

代码语言:txt
复制
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    
    <!-- 定义一个键来标识重复元素 -->
    <xsl:key name="elements-by-value" match="要删除重复的节点名称" use="."/>
    
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <!-- 只处理第一次出现的元素 -->
    <xsl:template match="要删除重复的节点名称[generate-id() = generate-id(key('elements-by-value', .)[1])]">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <!-- 忽略后续出现的重复元素 -->
    <xsl:template match="要删除重复的节点名称"/>
</xsl:stylesheet>

方法二:使用 XSLT 2.0 的 distinct-values 函数

代码语言:txt
复制
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="父节点名称">
        <xsl:copy>
            <!-- 获取不重复的子节点值 -->
            <xsl:for-each select="distinct-values(要删除重复的节点名称)">
                <xsl:copy>
                    <xsl:value-of select="."/>
                </xsl:copy>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

方法三:使用 preceding-sibling 轴

代码语言:txt
复制
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <!-- 只处理没有相同值的前驱兄弟节点的元素 -->
    <xsl:template match="要删除重复的节点名称[not(. = preceding-sibling::要删除重复的节点名称)]">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <!-- 忽略重复元素 -->
    <xsl:template match="要删除重复的节点名称"/>
</xsl:stylesheet>

实际示例

假设有以下 XML:

代码语言:txt
复制
<books>
    <book id="1">XML Basics</book>
    <book id="2">XSLT Guide</book>
    <book id="3">XML Basics</book>
    <book id="4">XPath Tutorial</book>
    <book id="5">XSLT Guide</book>
</books>

使用 Muenchian 分组法的完整解决方案:

代码语言:txt
复制
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:key name="books-by-title" match="book" use="."/>
    
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="book[generate-id() = generate-id(key('books-by-title', .)[1])]">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="book"/>
</xsl:stylesheet>

输出结果:

代码语言:txt
复制
<books>
    <book id="1">XML Basics</book>
    <book id="2">XSLT Guide</book>
    <book id="4">XPath Tutorial</book>
</books>

注意事项

  1. 方法一(Muenchian 分组)是 XSLT 1.0 中最有效的方法,特别适合处理大型 XML 文件
  2. 方法二需要 XSLT 2.0 或更高版本支持
  3. 方法三(preceding-sibling)在小文件上工作良好,但在大文件上性能较差
  4. 如果要基于属性值而非元素内容去重,只需修改 key 的 use 属性即可

应用场景

  • 数据清洗和规范化
  • 合并来自多个源的 XML 数据
  • 准备数据用于统计分析
  • 优化 XML 文档大小和结构
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

没有搜到相关的沙龙

领券