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

使用XSLT实现同名值对匹配替换的技术实现咨询

嘿,这个名值对替换的需求我熟,给你两种不同XSLT版本的解决方案,按需选用就行~

解决方案:XSLT实现同名值对替换

核心思路就是先把两个字符串拆分成独立的名值对,把替换值做成一个可快速查询的映射,再遍历原始值的每个条目,匹配到就替换值,没匹配到就保留原样,最后重新拼接成字符串。

XSLT 2.0+ 版本(推荐,代码更简洁)

如果你的XSLT处理器支持2.0及以上版本(比如Saxon、Altova XMLSpy这些),用这个方案最省心:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>

  <!-- 定义你的原始值和替换值参数 -->
  <xsl:param name="original_val" select="'xxx=123,iii=kos,123=hfj,i920=owp02'"/>
  <xsl:param name="replace_val" select="'xxx=abc,i920=23ew'"/>

  <xsl:template match="/">
    <!-- 把替换值转换成键值映射表 -->
    <xsl:variable name="replace-map" as="map(xs:string, xs:string)">
      <xsl:map>
        <xsl:for-each select="tokenize($replace_val, ',')">
          <xsl:variable name="parts" select="tokenize(., '=')"/>
          <xsl:map-entry key="$parts[1]" select="$parts[2]"/>
        </xsl:for-each>
      </xsl:map>
    </xsl:variable>

    <!-- 遍历处理原始值的每个名值对 -->
    <xsl:value-of select="
      for $pair in tokenize($original_val, ',')
      return
        let $parts := tokenize($pair, '='),
            $key := $parts[1]
        return
          if (map:contains($replace-map, $key))
          then concat($key, '=', $replace-map($key))
          else $pair
    " separator=","/>
  </xsl:template>
</xsl:stylesheet>

代码解释:

  • 用tokenize()函数直接按逗号拆分字符串,再按等号拆分每个名值对的键和值
  • 用xsl:map创建一个键值映射,后续可以快速查找某个键对应的替换值
  • 用for表达式遍历原始值的每个条目,检查映射里是否存在对应键:存在就用替换值,不存在就保留原条目
  • 最后用<xsl:value-of>加separator=","把处理后的条目重新拼接成结果字符串

XSLT 1.0 版本(兼容旧处理器)

如果你的环境只能用XSLT1.0(比如一些老的Java或.NET处理器),可以用递归模板+节点集的方式实现:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl">
  <xsl:output method="text"/>

  <!-- 定义你的原始值和替换值参数 -->
  <xsl:param name="original_val" select="'xxx=123,iii=kos,123=hfj,i920=owp02'"/>
  <xsl:param name="replace_val" select="'xxx=abc,i920=23ew'"/>

  <!-- 把替换值转换成可查询的节点集 -->
  <xsl:variable name="replace-nodes">
    <xsl:call-template name="split-pairs">
      <xsl:with-param name="str" select="$replace_val"/>
    </xsl:call-template>
  </xsl:variable>
  <xsl:variable name="replace-set" select="exsl:node-set($replace-nodes)/pair"/>

  <xsl:template match="/">
    <xsl:call-template name="process-original">
      <xsl:with-param name="str" select="$original_val"/>
    </xsl:call-template>
  </xsl:template>

  <!-- 递归处理原始字符串的每个名值对 -->
  <xsl:template name="process-original">
    <xsl:param name="str"/>
    <xsl:param name="delimiter" select="','"/>

    <xsl:variable name="first" select="substring-before(concat($str, $delimiter), $delimiter)"/>
    <xsl:variable name="rest" select="substring-after($str, $delimiter)"/>

    <!-- 拆分当前名值对的键和值 -->
    <xsl:variable name="key" select="substring-before(concat($first, '='), '=')"/>
    <xsl:variable name="original-value" select="substring-after($first, '=')"/>

    <!-- 查找对应的替换值 -->
    <xsl:variable name="new-value" select="$replace-set[@key = $key]/@value"/>

    <!-- 输出处理后的当前条目 -->
    <xsl:value-of select="concat($key, '=', if ($new-value) then $new-value else $original-value)"/>

    <!-- 递归处理剩余条目 -->
    <xsl:if test="$rest">
      <xsl:value-of select="$delimiter"/>
      <xsl:call-template name="process-original">
        <xsl:with-param name="str" select="$rest"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

  <!-- 递归拆分替换字符串为节点集 -->
  <xsl:template name="split-pairs">
    <xsl:param name="str"/>
    <xsl:param name="delimiter" select="','"/>

    <xsl:variable name="first" select="substring-before(concat($str, $delimiter), $delimiter)"/>
    <xsl:variable name="rest" select="substring-after($str, $delimiter)"/>

    <xsl:if test="$first">
      <pair key="{substring-before(concat($first, '='), '=')}" value="{substring-after($first, '=')}"/>
    </xsl:if>

    <xsl:if test="$rest">
      <xsl:call-template name="split-pairs">
        <xsl:with-param name="str" select="$rest"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

代码解释:

  • XSLT1.0没有内置的拆分函数,所以用递归模板split-pairs把替换值拆成<pair key="xxx" value="abc"/>这样的节点
  • 用exsl:node-set()把临时节点转换成可查询的节点集(大部分XSLT1.0处理器都支持EXSLT扩展)
  • 递归模板process-original遍历原始值的每个条目,查找替换节点集中是否有对应key的条目,有就替换值,没有保留原值
  • 最后拼接所有处理后的条目得到结果

注意事项

  • 上述代码假设你的名和值里都不包含逗号或等号,如果有特殊字符(比如值里带逗号),需要调整拆分逻辑(比如用其他分隔符或者处理转义)
  • 优先推荐XSLT2.0+版本,代码更简洁易维护,执行效率也更高

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:13:01