首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XSL多个搜索和替换函数

XSL多个搜索和替换函数
EN

Stack Overflow用户
提问于 2011-03-12 09:03:15
回答 4查看 10.8K关注 0票数 4

我尝试使用XSL translate()函数创建类似搜索和替换的函数,如下所示:

代码语言:javascript
复制
<xsl:template name="create-id">
    <xsl:param name="id" />
    <xsl:call-template name="search-and-replace">
        <xsl:with-param name="str" select="$id" />
        <xsl:with-param name="search">0123456789</xsl:with-param>
        <xsl:with-param name="replace">abcdefghij</xsl:with-param>
    </xsl:call-template>
</xsl:template>

<xsl:template name="search-and-replace">
    <xsl:param name="str" />
    <xsl:param name="search" />
    <xsl:param name="replace" />
    <xsl:variable name="newstr" select="translate($str, $search,
    $replace)" />
    <xsl:choose>
        <xsl:when test="contains($newstr, $search)">
            <xsl:call-template name="search-and-replace">
                <xsl:with-param name="str" select="$newstr" />
                <xsl:with-param name="search" select="$search" />
                <xsl:with-param name="replace" select="$replace" />
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$newstr" />
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

然而,我的逻辑有些地方是错误的,因为它似乎剥离了返回字符串中的最后一个字符。我猜translate()只是替换了字符串中每个字符的第一个实例,而不是真正的递归。

如有任何想法或意见,我们将不胜感激。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-03-13 00:24:27

删除translate() 函数只能用另一个单字符(或用空字符(delete))替换单个字符。因此它不能解决字符串替换的问题。

这里的是针对多替换问题的完整XSLT1.0解决方案

代码语言:javascript
复制
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my">
    <xsl:output omit-xml-declaration="yes"/>
    <xsl:strip-space elements="*"/>

    <my:params xml:space="preserve">
        <pattern>
            <old>&#xA;</old>
            <new><br/></new>
        </pattern>
        <pattern>
            <old>quick</old>
            <new>slow</new>
        </pattern>
        <pattern>
            <old>fox</old>
            <new>elephant</new>
        </pattern>
        <pattern>
            <old>brown</old>
            <new>white</new>
        </pattern>
    </my:params>

    <xsl:variable name="vPats"
         select="document('')/*/my:params/*"/>

    <xsl:template match="text()" name="multiReplace">
        <xsl:param name="pText" select="."/>
        <xsl:param name="pPatterns" select="$vPats"/>

        <xsl:if test="string-length($pText) >0">
            <xsl:variable name="vPat" select=
            "$vPats[starts-with($pText, old)][1]"/>

            <xsl:choose>
                <xsl:when test="not($vPat)">
                    <xsl:copy-of select="substring($pText,1,1)"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:copy-of select="$vPat/new/node()"/>
                </xsl:otherwise>
            </xsl:choose>

            <xsl:call-template name="multiReplace">
                <xsl:with-param name="pText" select=
                "substring($pText, 1 + not($vPat) + string-length($vPat/old/node()))"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

在以下XML文档上应用此转换时为

代码语言:javascript
复制
<t>The quick
brown fox</t>

生成所需的正确结果

代码语言:javascript
复制
The slow<br />white elephant

说明

  1. 使用递归调用自身的命名模板。
  2. 所有多个替换模式-->替换对在单个外部参数中提供,为方便起见,此处将其内联指定为全局级元素<my:params>
  3. 递归采用源字符串中的每个字符(从左到右),并在字符串中的此位置查找以此字符开头的第一个模式。
  4. 替换可以是字符串,也可以是任何节点。在此特定情况下,我们将每个NL字符替换为<br/>元素。
票数 9
EN

Stack Overflow用户

发布于 2011-03-12 17:22:04

translate($arg, $mapString, $transString)函数的定义如下:

返回$arg modified的值,以便$arg值中出现在$mapString值的某个位置N处的每个字符都已替换为出现在$transString值的位置N处的字符。

也就是说,它不会将一个子字符串替换为另一个字符串,而是将字符映射到其他字符。对于子字符串替换,使用类似于

代码语言:javascript
复制
<xsl:template name="search-and-replace">
  <xsl:param name="str"/>
  <xsl:param name="search"/>
  <xsl:param name="replace"/>
  <xsl:choose>
    <xsl:when test="contains($str, $search)">
      <xsl:value-of select="substring-before($str, $search)"/>
      <xsl:value-of select="$replace"/>
      <xsl:call-template name="search-and-replace">
        <xsl:with-param name="str" select="substring-after($str, $search)"/>
        <xsl:with-param name="search" select="$search"/>
        <xsl:with-param name="replace" select="$replace"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$str"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>
票数 3
EN

Stack Overflow用户

发布于 2011-03-12 12:16:21

看起来你永远不会是真的,因为你已经把$search中的所有字符都替换成了$replace中的

代码语言:javascript
复制
<xsl:variable name="newstr" select="translate($str, $search,
    $replace)" />

事前。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5280079

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档