Re: [xsl] XPath expression to perform 'keyword' query

Subject: Re: [xsl] XPath expression to perform 'keyword' query
From: "M. David Peterson" <conners_dad@xxxxxxx>
Date: Wed, 15 Oct 2003 20:53:19 -0600
Hi Richard,

The first thing you want to do to begin this project is to translate all of
the text you will be searching using the XPath translate() function.  It
works by taking the text from the selected context node, compares it to a
string of characters to find matches, and then translates it using another
string of characters...  The following is saying take this node, match the
characters in this node to the characters in this string, and then translate 
each matching character to the corresponding character in the third string:

translate(textNode, 'ABCD', 'abcd')

so for every upper case A found in the text it converts it to the
corresponding character in the third string, in this case lower case a.
Taking this one step further and utlizing this function in a practical
situation you would do this.

create to variables as such...

<xsl:variable name="upperCase" select="ABCDEFGHIJKLMNOPQRSTUVWXYZ"/>
<xsl:variable name="lowerCase" select="abcdefghijklmnopqrstuvwxyz"/>

Now, within your style sheet you can use these two variables to map against
each other anytime you need to translate a node.

The whole purpose of doing this is that the contains() function of XPath
(the function you will use to find matches in the text)is case sensitive.
So to ensure that all potential matches are found you simply convert all the 
characters from the text to either upper or lower case. Which one really 
doesn't matter.  You just want to make sure the characters in the search 
string and the characters in the current test node are of the same case. As 
such, you will need to translate the search string variables in a similar 
fashion.  However, because the search string will probably be the same for 
every iteration through your test file you can take advantage of using 
multiple variables to translate the string and then use the reference to the 
translated string throughout your code. I would do it like this:

Create a variable for the string you will search on:

<xsl:variable name="searchTextToTranslate" select="This is the Search
string"/>

Then create another variable that invokes the translation and holds the
value.

<xsl:variable name="translatedSearchText"
select="translate($searchTextToTranslate, $upperCase, $lowerCase)"/>

The final phase of this is to create the code that will translate the
selected textNode and then compare it against the search string for matches.

You do that like so:

contains(translate(textNode, $upperCase, $lowerCase), $translatedSearchText)

You would normally wrap the above in an <xsl:if> block but you could you 
<xsl:choose><xsl:when> if you have a combination of results you are looking 
for.  Below is the XML sample block and the XSLT that uses the above 
examples to process through the XML file.

XML block...

<article id="001" publishDate="10/15/03">
    <title>This is the title</title>
    <description>Heres a bunch of text to try and match against the text 
variable</description>
</article>

XSLT chunk...

<xsl:for-each select="//article">
    <xsl:if test="contains(translate(description, $upperCase, $lowerCase), 
$translatedSearchText)">
        <xsl:value-of select="title"/><br/>
        <xsl:value-of select="@publishDate"/><br/>
        <xsl:value-of select="description"/>
    </xsl:if>
</xsl:for-each>


The next step in this type of application is to try and fine tune things by 
using keys.  But this will get you to where you want to go.  When your ready 
to take the performance up a notch make another post to the list and ask 
about using keys for pattern matching.

I hope this helps you get started :)

Best regards,

M.





----- Original Message ----- 
From: "Richard Lewis" <richard.lewis@xxxxxxxxx>
To: <XSL-List@xxxxxxxxxxxxxxxxxxxxxx>
Sent: Wednesday, October 15, 2003 12:28 PM
Subject: [xsl] XPath expression to perform 'keyword' query


> I'm using the Sablorton (v1.0) XSL processor (which implements XSLT 1.0)
> (because I'm working from PHP, its XSLT extensions only support this
> processor).
>
> I've written a database-like XML document and I'm trying to write a 
> stylesheet
> to do a 'keyword' query (i.e. a query where the user supplies a number of
> keywords and the system returns all the records which contain those 
> words).
>
> The elements which correspond to database records are called 'item' (its a
> record library) and they contain other elements nested to various levels
> which contain all the data that the keyword search needs to examine.
>
> In the stylesheet I'm using an <xsl:for-each select="//item[...]"> element 
> but
> I'm completely stuck as to what XPath expression I could use to select the
> correct records.
>
> My attempts are not worth posting!
>
> Any thoughts would be very much appreciated.
>
> Cheers,
> Richard
>
> PS. I may, if necessary move to the SAXON proessor (using XSLT 2.0) and 
> use
> JSP instead of PHP.
>
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
>
> 

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


Current Thread