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

如何在XSLT中定位闭合标签前的特定字符串并为元素添加动态属性

没问题,这个需求在XSLT里完全可以实现,核心就是精准定位标签内容末尾的括号内数字串,而不是抓所有符合规则的匹配项。我给你拆解具体实现思路和代码:

核心思路

我们需要两步走:

  1. 找到div下的title或p元素,判断其文本内容是否以括号包裹的目标数字串结尾;
  2. 提取符合要求的串(数字总位数为2/4/6/10,允许带横杠分隔),作为div的id属性。

XSLT 2.0+ 解决方案(推荐)

XSLT 2.0及以上支持正则相关函数,实现起来更简洁:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 匹配div元素,添加id属性 -->
  <xsl:template match="div">
    <!-- 处理title元素的候选id -->
    <xsl:variable name="title-content" select="normalize-space(title/text())"/>
    <xsl:variable name="title-candidate" select="replace($title-content, '^.*\(([^\)]+)\)$', '$1')"/>
    <xsl:variable name="title-id" select="$title-candidate[
      string-length(translate(., '-', '')) = (2,4,6,10) 
      and $title-candidate != $title-content
    ]"/>

    <!-- 处理p元素的候选id -->
    <xsl:variable name="p-content" select="normalize-space(p/text())"/>
    <xsl:variable name="p-candidate" select="replace($p-content, '^.*\(([^\)]+)\)$', '$1')"/>
    <xsl:variable name="p-id" select="$p-candidate[
      string-length(translate(., '-', '')) = (2,4,6,10) 
      and $p-candidate != $p-content
    ]"/>

    <!-- 确定最终id:优先用title的匹配结果,没有则用p的 -->
    <xsl:variable name="final-id" select="$title-id | $p-id"/>

    <!-- 生成带id的div -->
    <div>
      <xsl:if test="$final-id">
        <xsl:attribute name="id" select="$final-id"/>
      </xsl:if>
      <!-- 复制原div的所有子内容 -->
      <xsl:apply-templates select="@* | node()"/>
    </div>
  </xsl:template>

  <!-- 默认模板:复制所有其他节点和属性,保证原XML结构不变 -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

代码解释

  • 正则匹配末尾括号:replace($content, '^.*\(([^\)]+)\)$', '$1') 只会提取字符串最后一对括号里的内容,中间出现的括号串会被忽略;
  • 验证数字位数:translate(., '-', '') 去掉串里的横杠,再用string-length统计数字总长度,确保是2/4/6/10位;
  • 优先级处理:优先从title提取,没有匹配结果再用p的,符合你给出的两种场景逻辑;
  • 默认模板:保证原XML的其他元素、属性完全保留,只修改div的id。

适配XSLT 1.0的方案

如果只能用XSLT 1.0(没有replace函数),可以用字符串截取的方式实现:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 匹配div元素 -->
  <xsl:template match="div">
    <xsl:variable name="title-id">
      <xsl:call-template name="extract-valid-id">
        <xsl:with-param name="text" select="normalize-space(title/text())"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="p-id">
      <xsl:call-template name="extract-valid-id">
        <xsl:with-param name="text" select="normalize-space(p/text())"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="final-id" select="concat($title-id, $p-id)"/>

    <div>
      <xsl:if test="$final-id != ''">
        <xsl:attribute name="id"><xsl:value-of select="$final-id"/></xsl:attribute>
      </xsl:if>
      <xsl:apply-templates select="@* | node()"/>
    </div>
  </xsl:template>

  <!-- 提取末尾括号内的有效id -->
  <xsl:template name="extract-valid-id">
    <xsl:param name="text"/>
    <xsl:if test="contains($text, '(') and substring($text, string-length($text)) = ')'">
      <xsl:variable name="open-pos" select="string-length(substring-before($text, ')'))"/>
      <xsl:if test="substring($text, $open-pos, 1) = '('">
        <xsl:variable name="candidate" select="substring($text, $open-pos + 1, string-length($text) - $open-pos - 1)"/>
        <xsl:variable name="digit-count" select="string-length(translate($candidate, '-', ''))"/>
        <xsl:if test="$digit-count = 2 or $digit-count = 4 or $digit-count = 6 or $digit-count = 10">
          <xsl:value-of select="$candidate"/>
        </xsl:if>
      </xsl:if>
    </xsl:if>
  </xsl:template>

  <!-- 默认复制模板 -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

这个方案用substring-before、substring等XSLT 1.0原生函数实现了相同的逻辑,只是代码稍长一些。

测试你的场景

  • 情况1:p文本末尾的(0123-45-6789)会被提取,数字总长度10,符合要求,最终div的id为0123-45-6789;
  • 情况2:title文本末尾的(0123-45)会被提取,数字总长度6,符合要求,最终div的id为0123-45,和你期望的输出完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 11:57:47