我尝试使用XSL translate()函数创建类似搜索和替换的函数,如下所示:
<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()只是替换了字符串中每个字符的第一个实例,而不是真正的递归。
如有任何想法或意见,我们将不胜感激。
发布于 2011-03-13 00:24:27
删除translate() 函数只能用另一个单字符(或用空字符(delete))替换单个字符。因此它不能解决字符串替换的问题。
这里的是针对多替换问题的完整XSLT1.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>
</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说明
<my:params>。<br/>元素。发布于 2011-03-12 17:22:04
translate($arg, $mapString, $transString)函数的定义如下:
返回
$argmodified的值,以便$arg值中出现在$mapString值的某个位置N处的每个字符都已替换为出现在$transString值的位置N处的字符。
也就是说,它不会将一个子字符串替换为另一个字符串,而是将字符映射到其他字符。对于子字符串替换,使用类似于
<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>发布于 2011-03-12 12:16:21
看起来你永远不会是真的,因为你已经把$search中的所有字符都替换成了$replace中的
<xsl:variable name="newstr" select="translate($str, $search,
$replace)" />事前。
https://stackoverflow.com/questions/5280079
复制相似问题