xsl-list
[Top] [All Lists]

Re: occurence of a word

2003-04-18 07:49:45

"Leena Kulkarni" <mulberrylist(_at_)yahoo(_dot_)co(_dot_)in> wrote in message
news:20030418093933(_dot_)81063(_dot_)qmail(_at_)web8102(_dot_)in(_dot_)yahoo(_dot_)com(_dot_)(_dot_)(_dot_)
If I have to make any occurence of one word bold, how
do I go about it?

Like if I have to make the word 'Word' bold whenever
it occurs in the document

<root>
<Tag1>Word</Tag1>
<Tag2>Word to be made bold</Tag2>
<Name>This is the Word</Name>
<Final>Wordings should not come in bold</Final>
</root>


Here's an FXSL solution.

FXSL has a template named "str-split-to-words", which given a string and a
list (string) of possible delimiters, produces a list of all words that are
delimited by the delimiters.

This is not exactly sufficient in solving the problem, because now we need
also to keep the sub-strings consisting of delimiters.

This is done by the template bellow:

strSplitWordDel.xsl:
-----------------------
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:str-split2words-func="f:str-split2words-func"
exclude-result-prefixes="xsl msxsl str-split2words-func"


   <xsl:import href="str-foldl.xsl"/>

   <str-split2words-func:str-split2words-func/>

    <xsl:template name="str-split-word-del">
      <xsl:param name="pStr"/>
      <xsl:param name="pDelimiters"/>

      <xsl:variable name="vsplit2wordsFun"
                    select="document('')/*/str-split2words-func:*[1]"/>

      <xsl:variable name="vrtfParams">
       <delimiters><xsl:value-of select="$pDelimiters"/></delimiters>
      </xsl:variable>

      <xsl:variable name="vResult">
       <xsl:call-template name="str-foldl">
         <xsl:with-param name="pFunc" select="$vsplit2wordsFun"/>
         <xsl:with-param name="pStr" select="$pStr"/>
         <xsl:with-param name="pA0" select="msxsl:node-set($vrtfParams)"/>
       </xsl:call-template>
      </xsl:variable>

      <xsl:copy-of select="msxsl:node-set($vResult)/*[position() > 1]"/>

    </xsl:template>

    <xsl:template match="str-split2words-func:*">
      <xsl:param name="arg1" select="/.."/>
      <xsl:param name="arg2"/>

      <xsl:copy-of select="$arg1/*[1]"/>
      <xsl:copy-of select="$arg1/*[position() >= 2
                                 and position() != last()]"/>
      <xsl:variable name="vLastToken" select="$arg1/*[position() >
1][last()]"/>

      <xsl:choose>
        <xsl:when test="contains($arg1/*[1], $arg2)">
          <xsl:choose>
            <xsl:when test="$vLastToken[self::word]">
              <xsl:copy-of select="$vLastToken"/>
              <delim><xsl:copy-of select="$arg2"/></delim>
            </xsl:when>
            <xsl:otherwise>
             <delim><xsl:value-of select="concat($vLastToken,
$arg2)"/></delim>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:when>
        <xsl:otherwise>
          <xsl:choose>
             <xsl:when test="$vLastToken[self::word]">
               <word><xsl:value-of select="concat($arg1/word[last()],
$arg2)"/></word>
            </xsl:when>
            <xsl:otherwise>
             <xsl:copy-of select="$vLastToken"/>
             <word><xsl:copy-of select="$arg2"/></word>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

Now using the "str-split-word-del" template we can solve the problem:

test-strSplitWordDel2.xsl:
-----------------------------
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  xmlns:vendor="urn:schemas-microsoft-com:xslt"
  exclude-result-prefixes="vendor"


   <xsl:import href="identity.xsl"/>
   <xsl:import href="strSplitWordDel.xsl"/>

   <xsl:output omit-xml-declaration="yes"/>

   <xsl:variable name="vwSpecial" select="'Word'"/>
   <!-- to be applied on test-strSplitWordDel2.xsl -->

    <xsl:template match="text()">
      <xsl:variable name="vrtfSplit">
        <xsl:call-template name="str-split-word-del">
          <xsl:with-param name="pStr" select="."/>
          <xsl:with-param name="pDelimiters"
                          select="', &#9;&#10;&#13;'"/>
        </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="vSplit" select="vendor:node-set($vrtfSplit)/*"/>

      <xsl:call-template name="mergeTokens">
        <xsl:with-param name="pTokens" select="$vSplit"/>
        <xsl:with-param name="pboldWord" select="$vwSpecial"/>
      </xsl:call-template>
    </xsl:template>

    <xsl:template name="mergeTokens">
      <xsl:param name="pTokens" select="/.."/>
      <xsl:param name="pboldWord"/>

      <xsl:for-each select="$pTokens">
        <xsl:choose>
          <xsl:when test="self::word and . = $pboldWord">
            <b><xsl:value-of select="."/></b>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="."/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

When the above transformation is applied to the original source.xml:

<root>
  <Tag1>Word</Tag1>
  <Tag2>Word to be made bold</Tag2>
  <Name>This is the Word</Name>
  <Final>Wordings should not come in bold</Final>
</root>

the wanted result is produced:

<root>
  <Tag1><b>Word</b></Tag1>
  <Tag2><b>Word</b> to be made bold</Tag2>
  <Name>This is the <b>Word</b></Name>
  <Final>Wordings should not come in bold</Final>
</root>


Hope this helped.


=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL




 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



<Prev in Thread] Current Thread [Next in Thread>