[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: [xsl] How to Tag Several Words in a Given String


Subject: RE: [xsl] How to Tag Several Words in a Given String
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Fri, 14 Oct 2005 08:38:58 +0100

You can't do this with "for" or "for each", because that processes all the
items in the sequence in parallel, and you want to process them
sequentially. You need a recursive solution:

<xsl:function name="f:replace-all">
  <xsl:param name="input" as="xs:string"/>
  <xsl:param name="words-to-replace" as="xs:string*"/>
  <xsl:param name="replacement" as="xs:string"/>
  <xsl:sequence select="if (exists($words-to-replace))
          then f:replace-all(replace($in, $words-to-replace, $replacement))
          else $input"/>
</xsl:function>

The only drawback with this is that replace() expects a regular expression
rather than a string of characters to be replaced: so "S. Jean" would have
to be "S \. Jean". You can either convert your words to regular expressions
by escaping special characters, or you can use your own function in place of
replace(), implemented by recursive application of contains(),
substring-before(), etc.

Also, this replaces the words with replacement strings, not with elements.
But it should get you started.

Michael Kay
http://www.saxonica.com/


> -----Original Message-----
> From: UlyLee [mailto:ulyleeka@xxxxxxxxx] 
> Sent: 14 October 2005 05:04
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: RE: [xsl] How to Tag Several Words in a Given String
> 
> I'm still trying solutions for this problem.
> 
> my source xml:
> 
> <String>YA Cahier de brouillon Tual S. Jean</String>
> 
> I tried this xsl:
> 
> <xsl:variable name="strMatches" as="xs:string*"
> select="('YA', 'Tual', 'S. Jean')"/>
> 
> <xsl:template match="String">
> <xsl:element name="{name(.)}">
> <xsl:value-of select="for $i in (1 to
> count($strMatches)) return
> replace(text(),$strMatches[$i],'test')"/>
> </xsl:element>
> </xsl:template>
> 
> but it only gives me:
> 
> <String>test Cahier de brouillon Tual S. Jean YA
> Cahier de brouillon test S. Jean YA Cahier de
> brouillon Tual test</String>
> 
> as you can see i can only get to change each string in
> $strMatches per iteration but i want to output only
> one single string.
> 
> desired output is:
> 
> <String>test Cahier de brouillon test test</String>
> 
> am i close to solving this problem or am i way far
> out???
> 
> -- UlyLee
> --- UlyLee <ulyleeka@xxxxxxxxx> wrote:
> 
> > I actually had an idea on how to go around with this
> > but i dont how to properly code it in XSLT.
> > 
> > <String>Name1 and Name3 also Name4 Name5 but not
> > Name2</String>
> > 
> > <table>
> > <tr>
> > <td>Name1</td>
> > <td>ValidName1</td>
> > </tr>
> > <tr>
> > <td>Name3</td>
> > <td>ValidName3</td>
> > </tr>
> > <tr>
> > <td>Name4 Name5</td>
> > <td>ValidName4 ValidName5</td>
> > </tr>
> > </table>
> > 
> > * i'll assign first into a variable, validStr, all
> > the
> > td[1] in table
> > * test if contents of String is equal to $validStr
> > * if true then i'll assign to a variable, match, the
> > sibling of the td[1] that matches $validStr[1]
> > * then call replace(String, $validStr[1], $match)
> > * then run this all over again but this time passing
> > the replaced string as new string to process and
> > remove the $validStr[1] in $validStr to avoid
> > repetition.
> > 
> > output should be:
> > 
> > <String><ValidName>ValidName1</ValidName> and
> > <ValidName>ValidName3</ValidName> also
> > <ValidName>ValidName4 ValidName5</ValidName> but not
> > Name2</String>
> > 
> > i hope that makes sense :D
> > 
> > -- UlyLee
> > 
> > 
> > 		
> > __________________________________ 
> > Start your day with Yahoo! - Make it your home page!
> > 
> > http://www.yahoo.com/r/hs
> > 
> > 
> 
> 
> 
> 	
> 		
> __________________________________ 
> Yahoo! Mail - PC Magazine Editors' Choice 2005 
> http://mail.yahoo.com


Current Thread