[XSL-LIST Mailing List Archive Home]
[By Thread]
[By Date]
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:
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: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: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:template>
Re: [xsl] multiple replace
Subject: Re: [xsl] multiple replace From: "Sam Byland" <shbyland@xxxxxxxxxxx> Date: Tue, 12 Aug 2008 09:51:18 -0400 |
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><<</replace> <with>“</with> </replacements> <replacements> <replace>>></replace> <with>”</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>
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] multiple replace, Jim_Albright | Thread | [xsl] define a global variable and , henry human |
Re: [xsl] Cost of complex match pat, Florent Georges | Date | [xsl] define a global variable and , henry human |
Month |
Keywords