I'm trying to perform a string replace through XSLT, but I actually see no way for that in Firefox.
When I use the XSLT 2.0 replace() function through something like this:
<xsl:value-of select="replace(., 'old', 'new')"/>
I get in Firef开发者_开发知识库ox the error "An unknown XPath extension function was called". When I try to use any XSLT 1.0 compatible template that performs the replacement I get the error "XSLT Stylesheet (possibly) contains a recursion" (of course it contains a recursion, I see no other way for performing a string replacement in XSLT without a recursive function).
So, no chance to use the XSLT 2.0 replace() function, and no chance to use a recursive template. How do I perform the trick using XSLT? Please no suggestions to make it on the server side, I implemented my whole website in order to operate client-side only transformations and I can't roll back just because of one issue, and it's not right that in 2011 I can't use a powerful technology like XSLT because of its buggy and incomplete implementations.
EDIT:
The code I used is the same provided here: XSLT Replace function not found
I used this XML for testing:
<?xml version="1.0"?>
<?xml-stylesheet href="/example.xsl" type="text/xsl"?>
<content>lol</content>
and this XSLT:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template name="string-replace-all">
<xsl:param name="text"/>
<xsl:param name="replace"/>
<xsl:param name="by"/>
<xsl:choose>
<xsl:when test="contains($text,$replace)">
<xsl:value-of select="substring-before($text,$replace)"/>
<xsl:value-of select="$by"/>
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="substring-after($text,$replace)"/>
<xsl:with-param name="replace" select="$replace"/>
<xsl:with-param name="by" select="$by"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="content">
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="lolasd"/>
<xsl:with-param name="replace" select="lol"/>
<xsl:with-param name="by" select="asd"/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>
On Firefox I get "XSLT Stylesheet (possibly) contains a recursion". Well, of course it does, otherwise it wouldn't be a string replacement template. Other templates picked up around the net using the same style trigger the same issue as well.
With this document
<content>lol</content>
these parameters
<xsl:with-param name="text" select="lolasd"/>
<xsl:with-param name="replace" select="lol"/>
<xsl:with-param name="by" select="asd"/>
will be empty, and therefore this condition
<xsl:when test="contains($text,$replace)">
will always be true, and your code will recurse ad infinitum.
I guess your intention was to select a string instead a node in your <xsl:with-param>
elements but you forgot to use quotes/apostrophes. What you should have is something like
<xsl:with-param name="replace" select="'lol'"/>
Nevertheless, you should add a check for a case, where parameters are empty to avoid such problem, if you end up selecting emtpy strings.
精彩评论