Reputation: 53944
I am trying to modify strings like:
Some {words} should be {bold} ...
to something like
Some <b>words</b> should be <b>bold</b> ...
However, my implementation forgets all <b>
elements but the last one:
Some words should be <b>bold</b> ...
I think, that the substring-before() removes the already inserted <b>
elements.
Here is my code:
<xsl:template name="replace">
<xsl:param name="input"/>
<xsl:variable name="before" select="substring-before( $input, '{' )" />
<xsl:variable name="after" select="substring-after( $input, '}' )" />
<xsl:variable name="replace" select="substring-after( substring-before( $input, '}' ), '${' )" />
<xsl:choose>
<xsl:when test="$replace">
<xsl:call-template name="replace">
<xsl:with-param name="input">
<xsl:value-of select="$before" />
<xsl:element name="b">
<xsl:value-of select="$replace" />
</xsl:element>
<xsl:value-of select="$after" />
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$input" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Any ideas? Thanks for your help.
Upvotes: 0
Views: 1395
Reputation: 167571
As you have tagged the question as XSLT 2.0 I strongly suggest to use analyze-string
i.e. with
<text>Some {words} should be {bold} ...</text>
and the stylesheet
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:template match="text">
<xsl:analyze-string select="." regex="\{{(.*?)\}}">
<xsl:matching-substring>
<b>
<xsl:value-of select="regex-group(1)"/>
</b>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
outputs
Some <b>words</b> should be <b>bold</b> ...
Upvotes: 1
Reputation: 53944
I found the answer myself ...
Pass only the remaining string as a parameter to the recursive call:
<xsl:template name="replace">
<xsl:param name="input"/>
<xsl:variable name="before" select="substring-before( $input, '{' )" />
<xsl:variable name="after" select="substring-after( $input, '}' )" />
<xsl:variable name="replace" select="substring-after( substring-before( $input, '}' ), '${' )" />
<xsl:choose>
<xsl:when test="$replace">
<!-- moved outside the recursive call -->
<xsl:value-of select="$before" />
<xsl:element name="b">
<xsl:value-of select="$replace" />
</xsl:element>
<xsl:call-template name="replace">
<xsl:with-param name="input">
<xsl:value-of select="$after" />
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$input" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
So the substring-before() function was not the problem ...
Upvotes: 0