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

XSLT 3.0:将数字字符替换为英文单词形式的实现求助

解决XSLT中XML元素名数字转英文单词的问题

你之前的思路方向是对的,但问题出在直接用整个属性值去匹配map的键——map只会返回完全匹配的键对应的值,而不会逐个字符替换数字。要实现把字符串里每个数字都换成对应的英文单词,我们需要逐个处理字符串中的每个字符,或者用正则匹配替换的方式来实现。

方案一:XSLT 3.0(推荐,适配你已用到的map特性)

首先定义数字到英文单词的映射map,然后用analyze-string配合函数式替换来逐个处理每个数字字符:

<!-- 定义数字到单词的映射 -->
<xsl:variable name="digit-word-map" as="map(xs:string, xs:string)" select="
  map {
    '0': 'zero', '1': 'one', '2': 'two', '3': 'three',
    '4': 'four', '5': 'five', '6': 'six', '7': 'seven',
    '8': 'eight', '9': 'nine'
  }
"/>

<!-- 处理属性值,替换所有数字为对应单词 -->
<xsl:value-of select="
  analyze-string(current()/@name, '\d')
  => replace(
    function($match) {
      $digit-word-map($match[1])  <!-- 取出匹配的数字,从map中获取对应单词 -->
    }
  )
"/>

效果验证:

  • 3RD_RACK → threeRD_RACK
  • ENERGY_CLASS_2010 → ENERGY_CLASS_twozeroonezero
  • PROGRAMMDAUERPROGRAM1 → PROGRAMMDAUERPROGRAMone

analyze-string会把输入字符串按正则\d(匹配单个数字)拆分,然后replace方法用自定义函数把每个匹配到的数字替换成map里对应的单词,完美实现你要的效果。

如果你习惯用遍历字符的方式,也可以这样写:

<xsl:value-of select="
  string-join(
    for $char in string-to-codepoints(current()/@name) => codepoints-to-string()
    return
      if ($char castable as xs:integer)
      then $digit-word-map($char)
      else $char,
    ''
  )
"/>

这段代码会把字符串拆成单个字符,逐个判断是否是数字,如果是就取map里的单词,否则保留原字符,最后用string-join拼接成完整字符串。

方案二:XSLT 2.0(如果无法使用XSLT 3.0特性)

如果你的环境不支持XSLT 3.0的map和函数式操作,可以用递归模板来逐个处理字符:

<xsl:template name="replace-digits-with-words">
  <xsl:param name="input-string"/>
  <xsl:if test="$input-string">
    <!-- 取第一个字符 -->
    <xsl:variable name="first-char" select="substring($input-string, 1, 1)"/>
    <!-- 判断是否是数字,替换成对应单词 -->
    <xsl:choose>
      <xsl:when test="$first-char = '0'">zero</xsl:when>
      <xsl:when test="$first-char = '1'">one</xsl:when>
      <xsl:when test="$first-char = '2'">two</xsl:when>
      <xsl:when test="$first-char = '3'">three</xsl:when>
      <xsl:when test="$first-char = '4'">four</xsl:when>
      <xsl:when test="$first-char = '5'">five</xsl:when>
      <xsl:when test="$first-char = '6'">six</xsl:when>
      <xsl:when test="$first-char = '7'">seven</xsl:when>
      <xsl:when test="$first-char = '8'">eight</xsl:when>
      <xsl:when test="$first-char = '9'">nine</xsl:when>
      <xsl:otherwise><xsl:value-of select="$first-char"/></xsl:otherwise>
    </xsl:choose>
    <!-- 递归处理剩余字符 -->
    <xsl:call-template name="replace-digits-with-words">
      <xsl:with-param name="input-string" select="substring($input-string, 2)"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>

使用这个模板时,只需要传入属性值即可:

<xsl:call-template name="replace-digits-with-words">
  <xsl:with-param name="input-string" select="current()/@name"/>
</xsl:call-template>

为什么你之前的代码不生效?

你之前写的$MyMap(current()/@name)是把整个属性值作为键去查map,比如当属性值是3RD_RACK时,map里没有这个键,所以返回空;只有当属性值是单个数字(比如3)时,才会返回three。这就是为什么你只能得到数字部分的原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:35:25