XSL 多重搜索替换功能 [英] XSL Multiple search and replace function

查看:44
本文介绍了XSL 多重搜索替换功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am attempting to use the XSL translate() function to create something like a search and replace function as follows:

<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() 只是替换字符串中每个字符的第一个实例,并不是真正的递归.

However, something about my logic is wrong here as it appears to be stripping off the last character in the returned string. My guess is that translate() is only replacing the first instance of each character in the string and is not truly recursive.

任何想法或意见将不胜感激.

Any thoughts or input would be appreciated.

推荐答案

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

The translate() function can only replace a single character with another single character (or with the empty character (delete)). Thus it cannot solve the problem of string replacement.

这是一个针对多重替换问题的完整 XSLT 1.0 解决方案:

<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 文档时:

<t>The quick
brown fox</t>

产生想要的、正确的结果:

The slow<br />white elephant

说明:

  1. 使用递归调用自身的命名模板.

  1. A named template that calls itself recursively is used.

所有多个替换模式 --> 替换对都在单个外部参数中提供,这里为了方便起见,将其内联指定为全局级元素 .

All multiple replacement pattern --> replacement pairs are provided in a single external parameter, which for convenience here is specified inline as the global-level element <my:params> .

递归获取源字符串中的每个字符(从左到右),并在字符串中的这个位置找到以该字符开头的第一个模式.

The recursion takes every single character in the source string (from left to right) and finds the first pattern that starts with this character at this position in the string.

替换不仅可以是字符串,也可以是任何节点.在这种特定情况下,我们将用 <br/> 元素替换每个 NL 字符.

The replacement can be not only a string but also any node. In this specific case we are replacing every NL character with a <br/> element.

这篇关于XSL 多重搜索替换功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆