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!

results matching ""

    No results matching ""