|
Subject: Re: [xsl] search and replace From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Thu, 29 Apr 2004 14:57:22 +0100 |
Hi Norma,
> I found this template on the list but am not sure how to implement
> it. I'm trying to replace ??degrees?? with ° 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="'°'" />
</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 '°' (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 |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| [xsl] search and replace, Norma Yeazell | Thread | [xsl] Sort by Parameters-Child Node, Bret |
| RE: [xsl] looping in xslt, Kenny Akridge | Date | Re: [xsl] looping in xslt, Jeni Tennison |
| Month |