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

使用XSL包裹XML中连续<b>元素的优化方案及空格问题咨询

优化连续<b>元素分组的XSLT方案 + 多余空格解决技巧

你提到的连续<b>元素分组问题,用XSLT 2.0及以上的xsl:for-each-group(group-adjacent特性)是目前最简洁高效的实现方式,比递归遍历或者兄弟节点判断要优雅得多。另外针对转换后出现的多余空格,也有几个针对性的处理方法,下面具体拆解:

一、更优的连续<b>分组实现

核心思路是利用group-adjacent属性,将相邻的<b>元素归为同一组,然后给每组套上你需要的容器标签(比如<bold-group>,可根据需求自定义)。非<b>元素则直接原样输出。

假设你的目标是把连续<b>包裹在<bold-group>中,示例XSLT代码如下:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 先关闭输出缩进,避免自动生成多余空格 -->
  <xsl:output method="xml" encoding="UTF-8" indent="no"/>

  <!-- 复制根节点<chap>,并处理其子节点 -->
  <xsl:template match="chap">
    <xsl:copy>
      <xsl:apply-templates select="p"/>
    </xsl:copy>
  </xsl:template>

  <!-- 处理<p>节点,对其子节点按是否为<b>进行相邻分组 -->
  <xsl:template match="p">
    <xsl:copy>
      <xsl:for-each-group select="node()" group-adjacent="name() = 'b'">
        <!-- 处理<b>节点组:套上容器标签 -->
        <xsl:if test="current-grouping-key()">
          <bold-group>
            <xsl:copy-of select="current-group()"/>
          </bold-group>
        </xsl:if>
        <!-- 处理非<b>节点:直接复制输出 -->
        <xsl:if test="not(current-grouping-key())">
          <xsl:copy-of select="current-group()"/>
        </xsl:if>
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>

  <!-- 默认模板:复制所有未匹配的节点和属性,保证其他内容不丢失 -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

这个方案的优势:

  • 代码简洁逻辑清晰,无需复杂的条件判断或递归
  • 支持任意数量的连续<b>,不管节点间是否有空白文本
  • 兼容XSLT 2.0及以上版本(如果必须用XSLT 1.0,只能通过递归模板实现,但复杂度会高很多,优先推荐2.0+)

二、解决转换后多余空格的问题

多余空格通常来自两个源头:原XML中的空白文本节点,或是XSLT输出时的自动缩进。可以从以下几个方向处理:

1. 过滤原XML中的纯空白文本节点

添加一个模板,直接忽略只包含空白的文本节点(不会影响内容中的正常空格):

<xsl:template match="text()[normalize-space() = '']"/>

如果只想过滤特定元素下的空白(比如<p>内的节点间空白),可以更精准地匹配:

<xsl:template match="p/text()[normalize-space() = '']"/>

2. 调整输出设置

将<xsl:output>的indent设为no,避免XSLT处理器自动添加缩进空格:

<xsl:output method="xml" encoding="UTF-8" indent="no"/>

如果需要格式化输出又不想有多余空格,可以搭配xsl:strip-space指定要去除空格的元素:

<xsl:strip-space elements="p chap"/> <!-- 去除这些元素下的空白节点 -->

3. 处理组内的空白(可选)

如果原XML中连续<b>之间有空格(比如示例里<b>The</b> <b>Attorney</b>的中间空格),若不需要保留,可以在分组时过滤这些空白:

<xsl:if test="current-grouping-key()">
  <bold-group>
    <xsl:for-each select="current-group()[self::b]">
      <xsl:copy-of select="."/>
    </xsl:for-each>
  </bold-group>
</xsl:if>

这样会只保留<b>元素,自动剔除组内的空白文本节点。

测试效果

用你给出的输入片段:

<chap> 
  <p><b>The</b> <b>Attorney</b> General <b>(Fees)</b><b>a</b><b>b</b><b>c</b> Determination 2012 No 110 commenced on 1...</p>
</chap>

经过上述XSLT转换后,会输出:

<chap><p><bold-group><b>The</b><b>Attorney</b></bold-group> General <bold-group><b>(Fees)</b><b>a</b><b>b</b><b>c</b></bold-group> Determination 2012 No 110 commenced on 1...</p></chap>

(若开启xsl:strip-space,会进一步清理节点间的冗余空白)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:28:44