XSLT 1.0 没有强大的文本搜索和替换功能。您可以使用contains
,substring-before
和substring-after
进行处理,但您必须使用递归模板来处理您尝试修复的字符串多次出现子字符串的情况。
这有效,假设您移动和重命名元素的变换是恒等变换的变体:
<xsl:template match="text()">
<xsl:call-template name="replace">
<xsl:with-param name="text" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="replace">
<xsl:param name="text"/>
<xsl:choose>
<xsl:when test="contains($text, 'bar')">
<xsl:call-template name="replace">
<xsl:with-param name="text" select="concat(
substring-before($text, 'bar'),
'myBar',
substring-after($text, 'bar'))"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
请注意,在使用 复制元素值的任何地方value-of
,都需要使用apply-templates
; 改变这个:
<xsl:template match="someElement">
<renamedElement>
<xsl:value-of select="."/>
<renamedElement>
</xsl:template>
进入这个:
<xsl:template match="someElement">
<renamedElement>
<xsl:apply-templates select="text()"/>
<renamedElement>
</xsl:template>
进行多次替换有点棘手。您必须扩展replace
模板以获取 asearchFor
和replaceWith
参数,这很容易,然后在text()
模板中执行此操作:
<xsl:variable name="pass1">
<xsl:call-template name="replace">
<xsl:with-param name="text" select="."/>
<xsl:with-param name="searchFor">bar</xsl:with-param>
<xsl:with-param name="replaceWith">myBar</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="pass2">
<xsl:call-template name="replace">
<xsl:with-param name="text" select="."/>
<xsl:with-param name="searchFor">bar</xsl:with-param>
<xsl:with-param name="replaceWith">myBar</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$pass2"/>
在支持在文本节点上使用正则表达式的 XSLT 2.0 中,这要容易得多。您仍然创建一个匹配的模板text()
,但它只是调用了replace
. 如果您有幸能够使用 XSLT 2.0,请参阅这篇文章以获取大量信息。