![]() |
|
|||
|
Hi I want to highlight (make it bold) a word in some text I'm getting in XML format. My plan was to replace the word with a bold (or span) tag with the word within the tag. I've found the code below and it works fine as long as I'm not adding tags around the to parameter. Can anyone explain to me why it doesn't work with tags? And it needs to be XSLT 1.0. This works: X<xsl:value-of select="'little steak'"/>X This doesn't work: <b><xsl:value-of select="'little steak'"/></b> And the code: <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <!-- reusable replace-string function --> <xsl:template name="replace-string"> <xsl aram name="text"/><xsl aram name="from"/><xsl aram name="to"/><xsl:choose> <xsl:when test="contains($text, $from)"> <xsl:variable name="before" select="substring-before($text, $from)"/> <xsl:variable name="after" select="substring-after($text, $from)"/> <xsl:variable name="prefix" select="concat($before, $to)"/> <xsl:value-of select="$before"/> <xsl:value-of select="$to"/> <xsl:call-template name="replace-string"> <xsl:with-param name="text" select="$after"/> <xsl:with-param name="from" select="$from"/> <xsl:with-param name="to" select="$to"/> </xsl:call-template> </xsl:when> <xsl therwise><xsl:value-of select="$text"/> </xsl therwise></xsl:choose> </xsl:template> <!-- test the function --> <xsl:template match="/"> <xsl:call-template name="replace-string"> <xsl:with-param name="text" select="'Mary had a little lamb, little lamb, little lamb.'"/> <xsl:with-param name="from" select="'little lamb'"/> <xsl:with-param name="to"> <!-- X<xsl:value-of select="'little steak'"/>X --> <b><xsl:value-of select="'little steak'"/></b> </xsl:with-param> </xsl:call-template> </xsl:template> </xsl:stylesheet> |
|
|||
|
Hvid Hat wrote:
> I want to highlight (make it bold) a word in some text I'm getting in > XML format. My plan was to replace the word with a bold (or span) tag > with the word within the tag. I've found the code below and it works > fine as long as I'm not adding tags around the to parameter. Can anyone > explain to me why it doesn't work with tags? And it needs to be XSLT 1.0. You are using <xsl:value-of select="$to"/>, that outputs a text node with the string value, it does not create elements. Assuming you do not want to replace a substring but rather wrap it into an element (e.g. b element) then use the following: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template name="wrap"> <xsl aram name="text"/><xsl aram name="search"/><xsl aram name="element-name"/><xsl:choose> <xsl:when test="contains($text, $search)"> <xsl:value-of select="substring-before($text, $search)"/> <xsl:element name="{$element-name}"> <xsl:value-of select="$search"/> </xsl:element> <xsl:call-template name="wrap"> <xsl:with-param name="text" select="substring-after($text, $search)"/> <xsl:with-param name="search" select="$search"/> <xsl:with-param name="element-name" select="$element-name"/> </xsl:call-template> </xsl:when> <xsl therwise><xsl:value-of select="$text"/> </xsl therwise></xsl:choose> </xsl:template> <xsl:template match="/"> <xsl:call-template name="wrap"> <xsl:with-param name="text" select="'Mary had a little lamb, little lamb, little lamb.'"/> <xsl:with-param name="search" select="'little lamb'"/> <xsl:with-param name="element-name" select="'b'"/> </xsl:call-template> </xsl:template> </xsl:stylesheet> -- Martin Honnen http://JavaScript.FAQTs.com/ |
|
|||
|
Martin Honnen wrote:
> Hvid Hat wrote: > >> I want to highlight (make it bold) a word in some text I'm getting in >> XML format. My plan was to replace the word with a bold (or span) tag >> with the word within the tag. I've found the code below and it works >> fine as long as I'm not adding tags around the to parameter. Can >> anyone explain to me why it doesn't work with tags? And it needs to be >> XSLT 1.0. > > You are using <xsl:value-of select="$to"/>, that outputs a text node > with the string value, it does not create elements. If you use xsl:copy-of as in <xsl:template name="replace-string"> <xsl aram name="text"/><xsl aram name="from"/><xsl aram name="to"/><xsl:choose> <xsl:when test="contains($text, $from)"> <xsl:variable name="before" select="substring-before($text, $from)"/> <xsl:variable name="after" select="substring-after($text, $from)"/> <xsl:variable name="prefix" select="concat($before, $to)"/> <xsl:value-of select="$before"/> <xsl:copy-of select="$to"/> <xsl:call-template name="replace-string"> <xsl:with-param name="text" select="$after"/> <xsl:with-param name="from" select="$from"/> <xsl:with-param name="to" select="$to"/> </xsl:call-template> </xsl:when> <xsl therwise><xsl:value-of select="$text"/> </xsl therwise></xsl:choose> </xsl:template> then I think you get what you want. -- Martin Honnen http://JavaScript.FAQTs.com/ |
|
|||
|
Thanks. Both your suggestions worked. Now I'm working on making the search
case-insensitive. Is there an easy way? Or can you guide me in the right direction? Hello Martin, > Martin Honnen wrote: > >> Hvid Hat wrote: >> >>> I want to highlight (make it bold) a word in some text I'm getting >>> in XML format. My plan was to replace the word with a bold (or span) >>> tag with the word within the tag. I've found the code below and it >>> works fine as long as I'm not adding tags around the to parameter. >>> Can anyone explain to me why it doesn't work with tags? And it needs >>> to be XSLT 1.0. >>> >> You are using <xsl:value-of select="$to"/>, that outputs a text node >> with the string value, it does not create elements. >> > If you use xsl:copy-of as in > > <xsl:template name="replace-string"> > <xsl aram name="text"/>> <xsl aram name="from"/>> <xsl aram name="to"/>> <xsl:choose> > <xsl:when test="contains($text, $from)"> > <xsl:variable name="before" select="substring-before($text, > $from)"/> > <xsl:variable name="after" select="substring-after($text, > $from)"/> > <xsl:variable name="prefix" select="concat($before, $to)"/> > <xsl:value-of select="$before"/> > <xsl:copy-of select="$to"/> > <xsl:call-template name="replace-string"> > <xsl:with-param name="text" select="$after"/> > <xsl:with-param name="from" select="$from"/> > <xsl:with-param name="to" select="$to"/> > </xsl:call-template> > </xsl:when> <xsl therwise>> <xsl:value-of select="$text"/> </xsl therwise>> </xsl:choose> </xsl:template> > then I think you get what you want. > |
|
|||
|
Hello Hvid,
Ok. Now I can replace the search string no matter what case it's in. Unfortunately I haven't found a way to keep the original case of the search sting in the text. Anyone? Here's my code: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:variable name="lcletters">abcdefghijklmnopqrstuvwxyz</xsl:variable> <xsl:variable name="ucletters">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable> <xsl:template name="replace-string"> <xsl aram name="text"/><xsl aram name="from"/><xsl aram name="to"/><xsl:choose> <xsl:when test="contains(translate($text, $ucletters, $lcletters), translate($from, $ucletters, $lcletters))"> <xsl:variable name="before" select="substring-before(translate($text, $ucletters, $lcletters), translate($from, $ucletters, $lcletters))"/> <xsl:variable name="after" select="substring-after(translate($text, $ucletters, $lcletters), translate($from, $ucletters, $lcletters))"/> <xsl:variable name="prefix" select="concat($before, $to)"/> <xsl:value-of select="$before"/> <xsl:copy-of select="$to"/> <xsl:call-template name="replace-string"> <xsl:with-param name="text" select="$after"/> <xsl:with-param name="from" select="$from"/> <xsl:with-param name="to" select="$to"/> </xsl:call-template> </xsl:when> <xsl therwise><xsl:value-of select="$text"/> </xsl therwise></xsl:choose> </xsl:template> <xsl:template match="/"> <xsl:call-template name="replace-string"> <xsl:with-param name="text" select="'Mary had a little lamb, LITTLE LAMB, x little lamb.'"/> <xsl:with-param name="from" select="'little lamb'"/> <xsl:with-param name="to"> <!-- X<xsl:value-of select="'little steak'"/>X --> <b> <xsl:value-of select="'little steak'"/> </b> </xsl:with-param> </xsl:call-template> </xsl:template> </xsl:stylesheet> > Thanks. Both your suggestions worked. Now I'm working on making the > search case-insensitive. Is there an easy way? Or can you guide me in > the right direction? > > Hello Martin, > >> Martin Honnen wrote: >> >>> Hvid Hat wrote: >>> >>>> I want to highlight (make it bold) a word in some text I'm getting >>>> in XML format. My plan was to replace the word with a bold (or >>>> span) tag with the word within the tag. I've found the code below >>>> and it works fine as long as I'm not adding tags around the to >>>> parameter. Can anyone explain to me why it doesn't work with tags? >>>> And it needs to be XSLT 1.0. >>>> >>> You are using <xsl:value-of select="$to"/>, that outputs a text node >>> with the string value, it does not create elements. >>> >> If you use xsl:copy-of as in >> >> <xsl:template name="replace-string"> >> <xsl aram name="text"/>>> <xsl aram name="from"/>>> <xsl aram name="to"/>>> <xsl:choose> >> <xsl:when test="contains($text, $from)"> >> <xsl:variable name="before" select="substring-before($text, >> $from)"/> >> <xsl:variable name="after" select="substring-after($text, >> $from)"/> >> <xsl:variable name="prefix" select="concat($before, $to)"/> >> <xsl:value-of select="$before"/> >> <xsl:copy-of select="$to"/> >> <xsl:call-template name="replace-string"> >> <xsl:with-param name="text" select="$after"/> >> <xsl:with-param name="from" select="$from"/> >> <xsl:with-param name="to" select="$to"/> >> </xsl:call-template> >> </xsl:when> <xsl therwise>>> <xsl:value-of select="$text"/> </xsl therwise>>> </xsl:choose> </xsl:template> >> then I think you get what you want. |
|
|||
|
Hvid Hat wrote:
> Hello Hvid, > > Ok. Now I can replace the search string no matter what case it's in. > Unfortunately I haven't found a way to keep the original case of the > search sting in the text. Anyone? Here's my code: > changing your variable assignents to <xsl:variable name="i" select="string-length(substring-before(translate($text, $ucletters, $lcletters), translate($from, $ucletters, $lcletters)))"/> <xsl:variable name="before" select="substring($text,1,$i)"/> <xsl:variable name="after" select="substring($text,1+$i+string-length($from))"/> will preserve the case of unmatched text (Mary in the example) If you mean you need to replace LITTLE LAMB by <b>LITTLE STEAK</b> ie make the replacement text match the case of the input, you have to work a bit harrder, especially to say exactly what that means for mixed case text. David As I suspect you are aware this would be far easier in xslt 2. -- http://dpcarlisle.blogspot.com |
|
|||
|
Hvid Hat wrote:
> Hello Hvid, > > Ok. Now I can replace the search string no matter what case it's in. > Unfortunately I haven't found a way to keep the original case of the > search sting in the text. Anyone? Here's my code: > changing your variable assignents to <xsl:variable name="i" select="string-length(substring-before(translate($text, $ucletters, $lcletters), translate($from, $ucletters, $lcletters)))"/> <xsl:variable name="before" select="substring($text,1,$i)"/> <xsl:variable name="after" select="substring($text,1+$i+string-length($from))"/> will preserve the case of unmatched text (Mary in the example) If you mean you need to replace LITTLE LAMB by <b>LITTLE STEAK</b> ie make the replacement text match the case of the input, you have to work a bit harrder, especially to say exactly what that means for mixed case text. David As I suspect you are aware this would be far easier in xslt 2. -- http://dpcarlisle.blogspot.com |
![]() |
| Thread Tools | Search this Thread |
| Display Modes | |
|
|