[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: search and replace

Subject: Re: search and replace
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Thu, 29 Apr 2004 14:57:22 +0100
xsl replace
Hi Norma,

> I found this template on the list but am not sure how to implement
> it. I'm trying to replace ??degrees?? with &#xb0; in all xml tags.
> Is it possible and can someone explain how this template
> would/should work?
>
> I've tried a few variations and I keep getting an error that
> call-template not allowed in stylesheet message.

I think that the error's arising because you've got the
<xsl:call-template> element at the top level of your stylesheet. It
can only appear within a template. Since you want to make the
replacement inside all the elements in your document, I suggest having
a template that matches all text nodes, and putting the template call
within that:

<xsl:template match="text()">
  <xsl:call-template name="_replace_string">
    <xsl:with-param name="string" select="." />
    <xsl:with-param name="find" select="'??degrees??'" />
    <xsl:with-param name="replace" select="'&#xB0;'" />
  </xsl:call-template>
</xsl:template>

Make sure that the templates that you have to process the elements
contain a <xsl:apply-templates> instruction to process their text node
children rather than a <xsl:value-of> instruction, otherwise this
template won't get used.

The <xsl:call-template> in the above template calls the template with
$string set to the value of the text node, $find set to the string
'??degrees??' and $replace set to the string '&#xB0;' (the degree
sign, I assume).

The _replace_string template is a recursive template that replaces all
the instances of $find in $string with $replace. It first tests to see
whether $string contains $find or not; if not, then all it has to do
is output $string itself.

> <xsl:choose>
>   <xsl:when test="contains($string,$find)">
[snip]
>   </xsl:when>
>   <xsl:otherwise>
>     <xsl:value-of select="$string"/>
>   </xsl:otherwise>
> </xsl:choose>

If $string *does* contain $find, then the template identifies the
substring before $find with substring-before($string, $find) and
outputs that, concatenated with the $replace string.

> <xsl:value-of
>   select="concat(substring-before($string,$find),$replace)"/>

Then the template moves on to the next part of the string, the
substring after the first instance of $find in $string. It calls the
template again, but with a different value for $string (this is the
recursive call):

> <xsl:call-template name="_replace_string">
>   <xsl:with-param name="string"
>     select="substring-after($string,$find)"/>
>   <xsl:with-param name="find" select="$find"/>
>   <xsl:with-param name="replace" select="$replace"/>
> </xsl:call-template>

I hope this explains things; come back to us with any questions.

Cheers,

Jeni

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

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.