You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用XSLT 1.0将重复XML标签归置到同一位置的需求

使用XSLT 1.0将重复同类型标签集中排列

输入XML

<?xml version="1.0" encoding="UTF-8"?>

<root>
<tag1>1</tag1>
<tag1_1>not repeating</tag1_1>
<tag2>2</tag2>
<tag3>3</tag3>
<tag4>4</tag4>
<tag5>5</tag5>
<tag6>6</tag6>
<tag2>2</tag2>
<tag3>3</tag3>
<tag1>1</tag1>
<tag4>4</tag4>
<tag1>1</tag1>
<tag3>3</tag3>
<tag2>2</tag2>
<tag4>4</tag4>
<tag4>4</tag4>
<tag2>2</tag2>
<tag1>1</tag1>
<tag3>3</tag3>
</root>

期望输出XML

<?xml version="1.0" encoding="UTF-8"?>

<root>
<tag1>1</tag1>
<tag1_1>not repeating</tag1_1>
<tag2>2</tag2>
<tag3>3</tag3>
<tag4>4</tag4>
<tag5>5</tag5>
<tag6>6</tag6>
<tag1>1</tag1>
<tag2>2</tag2>
<tag3>3</tag3>
<tag4>4</tag4>
<tag1>1</tag1>
<tag2>2</tag2>
<tag3>3</tag3>
<tag4>4</tag4>
<tag1>1</tag1>
<tag2>2</tag2>
<tag3>3</tag3>
<tag4>4</tag4>
</root>

XSLT 1.0解决方案

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
    
    <!-- 按元素名称分组,便于统计和获取实例 -->
    <xsl:key name="elem-by-name" match="root/*" use="local-name()"/>
    
    <!-- 获取所有唯一标签名,按首次出现顺序排列 -->
    <xsl:variable name="first-occurrence-names" select="root/*[generate-id() = generate-id(key('elem-by-name', local-name())[1])]/local-name()"/>
    
    <!-- 计算出现次数最多的标签的重复次数 -->
    <xsl:variable name="max-repeat-count">
        <xsl:for-each select="root/*[generate-id() = generate-id(key('elem-by-name', local-name())[1])]">
            <xsl:sort select="count(key('elem-by-name', local-name()))" data-type="number" order="descending"/>
            <xsl:if test="position() = 1">
                <xsl:value-of select="count(key('elem-by-name', local-name()))"/>
            </xsl:if>
        </xsl:for-each>
    </xsl:variable>
    
    <xsl:template match="/">
        <root>
            <!-- 先输出每个标签的第一个实例 -->
            <xsl:for-each select="$first-occurrence-names">
                <xsl:copy-of select="key('elem-by-name', .)[1]"/>
            </xsl:for-each>
            
            <!-- 循环输出后续的重复实例,按tag1、tag2、tag3、tag4的顺序分组 -->
            <xsl:for-each select="2 to $max-repeat-count">
                <xsl:variable name="current-index" select="."/>
                <xsl:for-each select="'tag1', 'tag2', 'tag3', 'tag4'">
                    <xsl:if test="count(key('elem-by-name', .)) >= $current-index">
                        <xsl:copy-of select="key('elem-by-name', .)[$current-index]"/>
                    </xsl:if>
                </xsl:for-each>
            </xsl:for-each>
        </root>
    </xsl:template>
</xsl:stylesheet>

工作原理

  1. 分组统计:通过<xsl:key>按元素名称分组,快速获取每个标签的所有实例和出现次数。
  2. 保留首次顺序:先输出所有标签的第一个实例,确保非重复标签(如tag1_1、tag5、tag6)只出现一次且位置不变。
  3. 循环输出重复项:根据最大重复次数,从第2个实例开始,按tag1→tag2→tag3→tag4的顺序依次输出对应索引的实例,实现集中排列的效果。

内容的提问来源于stack exchange,提问作者RaviRaj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 15:07:52