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 模板以获取searchFor 和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,请参阅 this article 以获取大量信息。