Strings: Replace
XSLT 1.0
does not provide any method that enables you to replace multi-character strings. translate
handles only single character replacements and replacing their groups with this method is either real pain or (close to) impossible.
Here is a utility template rectifying this problem:
<!--
- Utility function allowing multi-character string replacements.
-
- It replaces the `$needle` with `$replacement` one by one, recursively.
- Note that it is a `xsl:template` since `xsl:function` elements do not
- support recursion.
-->
<xsl:template name="utils:replace">
<xsl:param name="haystack" />
<xsl:param name="needle" />
<xsl:param name="replacement" />
<xsl:choose>
<!-- The `$haystack` contains the `$needle`. -->
<xsl:when test="contains($haystack, $needle)">
<xsl:value-of select="concat(
substring-before($haystack, $needle),
$replacement)" />
<!-- Resursive replacements in the rest of the string. -->
<xsl:call-template name="utils:replace">
<xsl:with-param name="haystack"
select="substring-after($haystack, $needle)" />
<xsl:with-param name="needle" select="$needle" />
<xsl:with-param name="replacement" select="$replacement" />
</xsl:call-template>
</xsl:when>
<!-- No `$needle` in the `$haystack` => simply return. -->
<xsl:otherwise>
<xsl:value-of select="$haystack" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
To enable invoking the utils:replace
directly from select
attributes, we recommend to couple the above xsl:template
with the following xsl:function
:
<!--
- Shortcut function allowing you to call e.g. simply
- `<xsl:value-of select="utils:replace('hello abc', 'abc', 'world')" />`
- instead of having to invoke a template via `xsl:call-template...`.
-->
<xsl:function name="utils:replace">
<xsl:param name="haystack" />
<xsl:param name="needle" />
<xsl:param name="replacement" />
<xsl:call-template name="utils:replace">
<xsl:with-param name="haystack" select="$haystack" />
<xsl:with-param name="needle" select="$needle" />
<xsl:with-param name="replacement" select="$replacement" />
</xsl:call-template>
</xsl:function>
And you are good to go!