[xsl] highlighting text template - please advise

Subject: [xsl] highlighting text template - please advise
From: Jakob <jakob@xxxxxxx>
Date: Sat, 28 Jul 2001 21:38:51 +0200 (MEST)
I need to highlight search terms/phrases in documents using xsl, just like in 
google's search result highlight feature.  With assistance of list members I 
have create a number of templates, among them one that recursively looks at 
cdata and highlights the potential search terms (see below).

The stylesheet must be able to highlight "foo" even though the search phrase 
is "Foo".  I have taken advice from the faq, and created the following 
template.  I would like to have advice from more experienced programmers 
regarding the efficiency of this template (and possibly receive ideas of how to 
improve it).

Actually, I would also like to add links before and after a hit, of the form

<a href='#hit1'>prev</a>
<a name='hit2'>Foo</a>
<a href='#hit3'>next</a>,

but only if there is a next or previous hit.  I would have to do a second pass,

I guess?  How else do I know if there is a next hit?

<xsl:variable name="uc" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:variable name="lc" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:param name='phrase'>foo</xsl:param>

<xsl:template match="text()" name="highlight" mode="search">
  <xsl:param name="phrase" select="''" />
  <!-- keep the original, mixed-case text for later -->
  <xsl:param name="originaltext" select="." />
      
  <!-- they are used for comparisons -->
  <xsl:param name="lctext" select="translate($originaltext, $lc, $uc)" />
  <xsl:param name="lcphrase" select="translate($phrase, $lc, $uc)" />

  <xsl:choose>
    <xsl:when test="contains($lctext, $lcphrase)">
      <!-- is this efficient? -->
      <xsl:value-of select="substring($originaltext, 1,
string-length(substring-
before($lctext, $lcphrase)))" />
      <em style='background: gold; font-weight: bold'>
      <!-- is this efficient? -->
      <xsl:value-of select="substring($originaltext, string-length(substring-
before($lctext, $lcphrase)) + 1, string-length($phrase))" />
      </em>
      <xsl:if test="$originaltext">
        <!-- is this efficient? -->
	<xsl:call-template name="highlight">
	  <xsl:with-param name="phrase" select="$phrase" />
	  <xsl:with-param name="originaltext" 
	    select="substring($originaltext, string-length(substring-before
($lctext, $lcphrase)) + 1+string-length($phrase))" />
	</xsl:call-template>
      </xsl:if>		
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$originaltext" />
    </xsl:otherwise>
  </xsl:choose>
</xsl:template> 

Thanks for your eyeballs ;-)
Jakob.

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


Current Thread