[xsl] XSL search

Subject: [xsl] XSL search
From: "Lewis, Russell" <Russell.Lewis@xxxxxxxxxxxxxxxx>
Date: Thu, 10 Jan 2008 16:07:20 -0500
Six months ago I decided to create a maintenance log using XML. At the
time I had never heard of XSLT, XPath or the DOM and almost wish I hadn't.
But now I'm chin deep in it and in the process I have had to learn some ASP
and VBScript. (Bonus? or Curse? hmmmm!)

Finally I thought I had it working. All of my ASP functions worked. All my
XSLT stylesheets transformed my XML perfectly. I even learned how to get
ASP to insert the current date into my input form. It even looked like
I had created a search engine but after I tested it more I realized how
lost I really am.

I want to be able to select a field (see search.xsl below) and then have
the user input the text to search for "within THAT field of ALL the XML
records". What I have done though is to create a search that searches
"within ALL fields for the input text". So if any record contains the
text in ANY field, that record is output to the transformation.

I have included portions of my code below:
search.xsl  sends "infield" and "intext" to processDOM.asp
processDOM.asp then sends them to searchOut.xsl as parameters named
        "searchfield" and "searchtext" respectively.
searchOut.xsl is the output table which uses "searchfield" and
       "searchtext" to search the XML document.
log.xml is a portion of the xml file

Thanks in advance for any advice.
Russ Lewis


----------------  search.xsl ----------------

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">
<xsl:template match="/">
   <html xmlns="http://www.w3.org/1999/xhtml";>
  <form id="search" name="search" method="post"><xsl:attribute
name="action">processDOM.asp?mode=search</xsl:attribute>
    <p>
     Select a Log Entry field to search and enter the text to search for.
    </p>
    <p>
      <select class="searchfield" name="infield" id="infield">
        <option id="equip" value="equip">Equipment</option>
       <option id="tdt" value="tdt">Date &amp; Time</option>
       <option id="flt" value="flt">Fault</option>
     </select>
    </p>
    <p>
      <input class="searchtext" name="intext" id="intext" type="text" />
    </p>
    <p>
     <a href="javascript:document.forms(0).submit();">Submit Search</a>
    </p>
   </form>
  </body>
 </html>
</xsl:template>

----------------  searchOut.xsl ----------------
<xsl:output method="html"/>
 <xsl:param name="searchfield"/>
 <xsl:param name="searchtext"/>
  <xsl:template match="/">
  <html xmlns="http://www.w3.org/1999/xhtml";>
  <table>
        <tr>
          <th>
            Equipment
          </th>
          <th>
            Date &amp; Time
          </th>
          <th>
           Fault
          </th>
      </tr>
----------------
Here is where it gets hairy! (and I lose mine)
----------------

           <xsl:for-each select="/log/logentry[$searchfield and contains(.,
$searchtext)]">

----------------
This search routine appeared to work at first but then
I realized that if you were to select the "eduip"
field and entered "1" as your text it will return with
every "logentry" in the output table because the "tdt"
field in the third "logentry" contains a "1".
After trying countless variations including the one
shown below as "XSL snippet" I am about to lose
what's left of my hair and my sanity!
----------------

             <tr>
                <td><a><xsl:attribute
name="href">processDOM.asp?mode=viewdetail&amp;path=/log/logentry[idx="<xsl:v
alue-of select="idx"/>"]</xsl:attribute><xsl:value-of
select="equip"/></a></td>
                <td><xsl:value-of select="tdt"/></td>
                <td><xsl:value-of select="flt"/></td>
              </tr>

      </xsl:for-each>

        </table>
      </p>
     </body>
    </html>
 </xsl:template>
</xsl:stylesheet>

----------------  XSL snippet ----------------

<xsl:template match="log">
  <xsl:for-each select="logentry">
    <xsl:sort select="node()[$searchfield]" order="ascending"/>
      <xsl:if test="contains(node()[position() = $searchfield],$searchtext)">
        <tr>
         <td><a><xsl:attribute name="href">processDOM ...


---------------- processDOM.asp ----------------

<%@ Language=VBScript %>
<%

... Other Functions up here ...

Function searchLog(strXMLFile, strXSLFile)
 Dim docDOM
 Dim docXSL
 Dim strField
 Dim strText
 Dim xslProc
 Dim xslt

    Set docDOM = Server.CreateObject("Msxml2.FreeThreadedDOMDocument.4.0")
    Set docXSL = Server.CreateObject("Msxml2.FreeThreadedDOMDocument.4.0")
    docDOM.validateOnParse = false
    docDOM.Async = false
    docDOM.Load(strXMLFile)
    docXSL.Load(strXSLFile)
    strField = Request.Form("infield")
    strText = Request.Form("intext")
    Set xslt = Server.CreateObject("MSXML2.XSLTemplate.4.0")
    Set xslt.Stylesheet = docXSL
    Set xslProc = xslt.CreateProcessor()
    xslProc.Input = docDOM
    xslProc.AddParameter "searchfield", CStr(strField)
    xslProc.AddParameter "searchtext", CStr(strText)
    xslProc.Output = Response
    xslProc.Transform
  Set docDOM = Nothing
  Set docXSL = Nothing
  Set xslProc = Nothing
  Set xslt = Nothing
End Function

Dim strMode
  strMode = Request.QueryString("mode")
  Select Case strMode
  Case "search"
     searchLog Server.MapPath("log.xml"), Server.MapPath("searchOut.xsl")
  Case "viewdetail"
     viewDetail ... Other Functions to view, edit, delete, etc.

----------------  log.xml ----------------
<log>
  <logentry>
    <equip>
     Device 1
    </equip>
    <tdt>
     1/8/2008 13:15
    </tdt>
    <flt>
    Broke
    </flt>
    <idx>
     9999991
    </idx>
  </logentry>
  <logentry>
    <equip>
     Device 1
    </equip>
    <tdt>
     1/8/2008 13:25
    </tdt>
    <flt>
    Broke
    </flt>
    <idx>
     9999992
    </idx>
  </logentry>
  <logentry>
    <equip>
     Device 2
    </equip>
    <tdt>
     1/8/2008 13:35
    </tdt>
    <flt>
    Broke
    </flt>
    <idx>
     9999993
    </idx>
 </logentry>
</log>

Current Thread
  • [xsl] XSL search
    • Lewis, Russell - Thu, 10 Jan 2008 16:07:20 -0500 <=
      • Message not available