xsl-list
[Top] [All Lists]

Re: [xsl] multiple replace

2008-08-12 06:52:12
Jim,

I remember doing something similar with XSLT 1.0, and it should work fine under 2.0 too. I created a new mode and passed the string to perform the multiple replace as a parameter; then applied templates changing the context to the "database" of find/replace characters. The template for that new mode performed the replace for that "record", then applied templates on the following sibling passing the new string along... Something like this:

Say you use the following variable for the various characters:

<xsl:variable name="ReplaceDb">
           <ReplaceTable>
                       <replacements>
                                   <replace>&lt;&lt;</replace>
                                   <with>&ldquo;</with>
                       </replacements>
                       <replacements>
                                   <replace>&gt;&gt;</replace>
                                   <with>&rdquo;</with>
                       </replacements>
etc
</xsl:variable>

Then if the string to perform the multiple replacements on is $String, I used something like this:

<xsl:apply-templates select="$ReplaceDb/*/*[1]" mode="DbStringReplace">
           <xsl:with-param name="InputString" select=" $String "/>
<xsl:with-param name="SearchCharacterName" select=" 'replace' "/>
           <xsl:with-param name="ReplaceCharacterName" select=" 'with' "/>
</xsl:apply-templates>

The XSLT 1.0 template rule I had hanging around for the "DbSringReplace" mode is pasted below. Note that it also calls a "StringSubstitute" template, but you can just use the replace() function for that... Also note I haven't used or testing this thing in a while :-)

Hope that helps!

Cheers,

...sam


<xsl:template match="*" mode="DbStringReplace">
           <xsl:param name="InputString"/>
           <xsl:param name="SearchCharacterName"/>
           <xsl:param name="ReplaceCharacterName"/>

           <xsl:choose>
                       <!-- first confirm strings aren't empty -->
<xsl:when test="$InputString = '' or $SearchCharacterName = '' or $ReplaceCharacterName = ''">
                                   <xsl:message>ERROR!!!</xsl:message>
                       </xsl:when>
                       <xsl:otherwise>

<xsl:variable name="SearchString" select="*[local-name()=$SearchCharacterName]"/> <xsl:variable name="ReplaceString" select="*[local-name()=$ReplaceCharacterName]"/>

                                   <xsl:variable name="UpdatedInputString">

                                               <xsl:choose>

<xsl:when test="not(contains($InputString[1], $SearchString))">

<xsl:value-of select="$InputString"/>

                                                           </xsl:when>
<xsl:otherwise> <!-- output string before SearchString, then output ReplaceString, then check is more in remaining part of InputString -->

<xsl:value-of select="concat(substring-before($InputString,$SearchString),$ReplaceString)"/>

<xsl:variable name="RemString" select="substring-after($InputString,$SearchString)"/>

                                                                       
<xsl:choose>
<xsl:when test="contains($RemString, $SearchString)"> <!-- if so, call recursively to finish replacing -->

<xsl:call-template name="StringSubstitute"> <xsl:with-param name="InputString" select="$RemString"/> <xsl:with-param name="SearchString" select="$SearchString"/> <xsl:with-param name="ReplaceString" select="$ReplaceString"/> </xsl:call-template>

</xsl:when>

<xsl:otherwise> <!-- output remainder of the string -->

<xsl:value-of select="substring-after($InputString,$SearchString)"/>

</xsl:otherwise>
                                                                       
</xsl:choose>

                                                           </xsl:otherwise>
                                               </xsl:choose>

                                   </xsl:variable>

                                   <xsl:choose>
<xsl:when test="following-sibling::*"> <!-- now process the next in line -->

<xsl:apply-templates select="following-sibling::*[1]" mode="DbStringReplace"> <xsl:with-param name="InputString" select="$UpdatedInputString"/> <xsl:with-param name="SearchCharacterName" select="$SearchCharacterName"/> <xsl:with-param name="ReplaceCharacterName" select="$ReplaceCharacterName"/>
                                                           
</xsl:apply-templates>

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

                       </xsl:otherwise>
           </xsl:choose>

</xsl:template>


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--