Hi,
Recapitulation of the problem
I want to search a string in a xml file and display the matched nodes.
The XML document looks like this :
<LIST>
<THEME label="Droit du travail" id="12"/>
<THEME label="droit social" id="2"/>
<THEME label="travail à la chaîne" id="34"/>
<THEME label="rien du tout" id="17"/>
</LIST>
The search engine only search on the labels attribute of the
THEME nodes of
this xml document and it display the @label.
...
The second problem is (it's less nescessary but would be great) :
I'd like to highlight the searched words in the displayed
result...how to ?
Turn the matching process around
<xsl:param name="string" select="'droit travail'"/>
<xsl:template name="tokenizer">
<xsl:param name="text" select="normalize-space($string)"/>
<xsl:choose>
<xsl:when test="contains($text, ' ')">
<xsl:choose>
<xsl:when test="contains(@label, substring-before($text, '
'))">true</xsl:when>
<xsl:otherwise>
<xsl:call-template name="tokenizer">
<xsl:with-param name="text" select="substring-after($text, ' ')"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$text and contains(@label, $text)">true</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template name="highlight">
<xsl:param name="label" select="@label"/>
<xsl:param name="text" select="normalize-space($string)"/>
<xsl:choose>
<xsl:when test="contains($text, ' ')">
<xsl:variable name="current" select="substring-before($text, ' ')"/>
<xsl:choose>
<xsl:when test="contains($label, $current)">
<xsl:call-template name="highlight">
<xsl:with-param name="label" select="substring-before($label,
$current)"/>
<xsl:with-param name="text" select="substring-after($text, ' ')"/>
</xsl:call-template>
<em>
<xsl:value-of select="$current"/>
</em>
<xsl:call-template name="highlight">
<xsl:with-param name="label" select="substring-after($label,
$current)"/>
<xsl:with-param name="text" select="substring-after($text, ' ')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="highlight">
<xsl:with-param name="label" select="$label"/>
<xsl:with-param name="text" select="substring-after($text, ' ')"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$text">
<xsl:choose>
<xsl:when test="contains($label, $text)">
<xsl:value-of select="substring-before($label, $text)"/>
<em>
<xsl:value-of select="$text"/>
</em>
<xsl:value-of select="substring-after($label, $text)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$label"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="LIST">
<form action="display.asp" method="post">
<input type="text" name="UserString"/>
<input type="submit" value="Go!"/>
</form>
<xsl:for-each select="THEME">
<xsl:variable name="match">
<xsl:call-template name="tokenizer"/>
</xsl:variable>
<xsl:if test="string($match)">
<xsl:call-template name="highlight"/>
<br/>
</xsl:if>
</xsl:for-each>
</xsl:template>
Using extensions would probably make the code shorter, e.g. just output
highlighting into a variable, cast that into a node-set and test if it contains
an em element to see if its a match.
Cheers,
Jarno - VNV Nation: Genesis
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list