Re: [xsl] search and replace multiple characters fails

Subject: Re: [xsl] search and replace multiple characters fails
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Sat, 20 Oct 2001 15:34:10 +0100
Hi Greg,

> I don't understand why this is happening. Can anyone see what is
> wrong here? ANd if there is a problem inherent for search and
> replace for multiple characters--how do other folks deal with it?

I can't quite work out what's going on with your templates, although
your problem might be coming from thinking that parameter values are
passed by reference whereas actually they're passed by value - it's
hard to tell.

The way that I'd go about this would be to generate some XML that
encoded the replacements that you want to perform, for example:

<replacements>
  <replace><from>&#8217;</from><to>&lt;\#39&gt;</to></replace>
  <replace><from>&#8226;</from><to>&lt;\#165&gt;</to></replace>
  ...
</replacements>

If you put this in replacements.xml, then you can get a node set
of the replace elements with:

  document('replacements.xml')/replacements/replace

You can use the following template to do the replacements. If the
string contains the first character, then the substring before the
character is passed to the same template, to do the rest of the
replacements. The string after the replaced character is passed to the
same template with the same set of replacements. If the string doesn't
contain the character, you move on to the next replacement (if there
is one) or just emit the string (if there isn't):

<xsl:template name="replace">
  <xsl:param name="string" />
  <xsl:param name="replacements"
             select="document('replacements.xml')/replacements/replace" />
  <xsl:variable name="first" select="$replacements[1]" />
  <xsl:variable name="rest" select="$replacements[position() > 1]" />
  <xsl:choose>
    <xsl:when test="contains($string, $first/from)">
      <xsl:call-template name="replace">
        <xsl:with-param name="string"
                        select="substring-before($string, $first/from)" />
        <xsl:with-param name="replacements" select="$rest" />
      </xsl:call-template>
      <xsl:copy-of select="$first/to" />
      <xsl:call-template name="replace">
        <xsl:with-param name="string"
                        select="substring-after($string, $first/from)" />
        <xsl:with-param name="replacements" select="$replacements" />
      </xsl:call-template>
    </xsl:when>
    <xsl:when test="$rest">
      <xsl:call-template name="replace">
        <xsl:with-param name="string" select="$string" />
        <xsl:with-param name="rest" select="$rest" />
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$string" />
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread