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

使用XSL合并同类型且class属性相同的节点

合并XML中相邻冗余的<span>标签解决方案

刚接触XSL就着手处理标签清理,这个方向很实用!针对你给出的XML里多个相邻span class="USous-article"需要合并的需求,我给你准备了两种XSLT方案,分别适配XSLT 2.0和1.0环境,你可以根据自己的工具版本选择:

先看你的XML示例:

<body><!-- userBodyTop goes here --> 
  <div class="header" /> 
  <div class="document"> 
    <p class="text">...</p> 
    <p class="Normal"> 
      <span class="USous-article">§ 1er </span> 
      <span class="USous-article">–</span> 
      <span class="USous-article"> </span>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus condime...
    </p>
  </div>
</body>

方案1:XSLT 2.0(推荐,语法更简洁)

利用XSLT 2.0的group-adjacent功能,可以轻松把相邻同class的span分组合并:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 身份模板:默认复制所有未被特殊匹配的节点/属性 -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- 匹配目标p标签,处理内部的span合并 -->
  <xsl:template match="p[contains(@class, 'Normal')]">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <!-- 按相邻节点类型分组:同class的span归为一组,其他节点各自成组 -->
      <xsl:for-each-group select="node()" group-adjacent="if (self::span[@class='USous-article']) then 'merge-span' else generate-id()">
        <xsl:choose>
          <!-- 处理需要合并的span组 -->
          <xsl:when test="current-grouping-key()='merge-span'">
            <span class="USous-article">
              <!-- 拼接组内所有span的文本内容 -->
              <xsl:value-of select="current-group()/text()"/>
            </span>
          </xsl:when>
          <!-- 其他节点原样输出 -->
          <xsl:otherwise>
            <xsl:apply-templates select="current-group()"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

说明:

  • 身份模板保证XML里其他未涉及的内容(比如header、text类p标签)完全保留原样。
  • 针对p class="Normal"内部的节点,我们把相邻的USous-article span归为一组,合并成一个span并拼接所有文本,非目标span的内容正常输出。

方案2:XSLT 1.0(兼容旧环境)

如果你的工具只支持XSLT 1.0,可以用递归模板来实现相同效果:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 身份模板:默认复制所有节点/属性 -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- 匹配第一个未被合并的USous-article span -->
  <xsl:template match="span[@class='USous-article'][not(preceding-sibling::node()[1][self::span[@class='USous-article']])]">
    <span class="USous-article">
      <!-- 递归收集所有相邻同class span的文本 -->
      <xsl:call-template name="merge-adjacent">
        <xsl:with-param name="current" select="."/>
      </xsl:call-template>
    </span>
    <!-- 跳过已合并的span,处理下一个非目标节点 -->
    <xsl:apply-templates select="following-sibling::node()[not(self::span[@class='USous-article'])][1]"/>
  </xsl:template>

  <!-- 跳过已经被合并的后续span -->
  <xsl:template match="span[@class='USous-article'][preceding-sibling::node()[1][self::span[@class='USous-article']]]"/>

  <!-- 递归模板:收集相邻同class span的文本 -->
  <xsl:template name="merge-adjacent">
    <xsl:param name="current"/>
    <xsl:value-of select="$current/text()"/>
    <!-- 如果下一个节点还是同class span,继续递归 -->
    <xsl:if test="$current/following-sibling::node()[1][self::span[@class='USous-article']]">
      <xsl:call-template name="merge-adjacent">
        <xsl:with-param name="current" select="$current/following-sibling::node()[1][self::span[@class='USous-article']]"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

说明:

  • 核心是通过递归找到所有连续的USous-article span,把它们的文本拼接起来输出成一个span。
  • 额外加了一个模板跳过已经被合并的后续span,避免重复输出。

内容的提问来源于stack exchange,提问作者R. BR

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:30:53