I originally cribbed this from O’Reilly’s XSLT Cookbook. It’s proven very handy at work, so I’ll dutifully type it out here…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<xsl:template name="search-and-replace">
  <xsl:param name="source-string" />
  <xsl:param name="search-string" />
  <xsl:param name="replacement-string" />

  <xsl:choose>
    <xsl:when test="$source-string and contains($source-string, $search-string)">
      <xsl:value-of select="substring-before($source-string, $search-string)" />
      <xsl:value-of select="$replacement-string" />

      <xsl:call-template name="search-and-replace">
        <xsl:with-param name="source-string" select="substring-after($source-string, $search-string)" />
        <xsl:with-param name="search-string" select="$search-string" />
        <xsl:with-param name="replacement-string" select="$replacement-string" />
      </xsl:call-template>

    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$source-string" />
    </xsl:otherwise>
  </xsl:choose>

</xsl:template>