[xsl] Including some records and excluding others in a search

Subject: [xsl] Including some records and excluding others in a search
From: "Lewis, Russell" <Russell.Lewis@xxxxxxxxxxxxxxxx>
Date: Thu, 28 Feb 2008 09:53:06 -0500
I am new to this and no doubt have gotten into something a little over my head
but
I've always believed in the "sink or swim" method of self teaching.
This XSL and XML are extracts of a much larger project of mine where the user
has
an input form (another stylesheet) that is read and then passes parameters to
this
stylesheet so it can use the contains() function to search the xml document
based
on the parameters passed.
I'm trying to learn how/do two things here:
1) If the user searches for "Data" ($searchtext = "Data") the output should
also
 include the fourth record because Field1 contains "all".
2) This stylesheet should also not display any records where Field1 contains
"info".
 I have a seperate stylesheet that will do that using the same method that is
 used to solve problem #1. This user doesn't have any links to the stylesheets
that
 would allow him to view a stylesheet that can view "info" records. I also
have the
 permissions of that stylesheet set so this user can't read them either. So
security
 is not a consideration here.
 Also I didn't include any attempts I've made in trying to accomplish this
because
 nothing has worked so far. I have, however, been able to use the line below
in the
 "textsearch" template to perform the "all" search but it is sloppy in that
"all" is
 not processed by the "Case Conversion" variable. (I wish it was.) I have not
been
 able to figure out if or how I might use the "not()" function to exclude
outputting
 "info" records.
 <xsl:for-each select="record[*[name() = $searchfield][contains(.,
$ProperText) or contains(., $UCASETEXT) or contains(., $lcasetext) or
../Field1[contains(., 'ALL') or contains(., 'all') or contains(., 'All')]]]">
XML Data
This is only a snippet of a much larger XML file normally kept in a separate
file
that is read by an ASP VBScript using the "Msxml2.FreeThreadedDOMDocument.4.0"
Load
method and parameters are output via the "MSXML2.XSLTemplate.4.0" AddParameter
method.
<?xml version="1.0"?>
<data>
  <record>
    <Field1>Data1-1</Field1>
    <Field2>Data1-2</Field2>
    <dtmField>2008-01-28T01:01:00Z</dtmField>
  </record>
  <record>
    <Field1>Info</Field1>
    <Field2>Data2-2</Field2>
    <dtmField>2008-01-28T02:02:00Z</dtmField>
  </record>
  <record>
    <Field1>Data3-1</Field1>
    <Field2>Data3-2</Field2>
    <dtmField>2008-01-28T03:03:00Z</dtmField>
  </record>
  <record>
    <Field1>all</Field1>
    <Field2>Data4-2</Field2>
    <dtmField>2008-01-28T04:04:00Z</dtmField>
  </record>
  <record>
    <Field1>All</Field1>
    <Field2>Data5-2</Field2>
    <dtmField>2008-01-28T05:05:00Z</dtmField>
  </record>
  <record>
    <Field1>info</Field1>
    <Field2>Data6-2</Field2>
    <dtmField>2008-01-28T06:06:00Z</dtmField>
  </record>
</data>
XSL Stylesheet
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">
  <xsl:output method="html"/>
<!--
The "selected" value of thes parameters are filled in for this example.
Normally
they are passed from an external ASP VBScript that processes inputs from
another
form where the values are input by the user.
-->
  <xsl:param name="searchfield" select="Field1"/>
  <xsl:param name="searchtext" select="Data"/>
  <xsl:param name="sortbyfield" select="Field2"/>
  <xsl:param name="sortbydate" select="1"/>
  <xsl:param name="sortorder" select="Descending"/>
  <xsl:param name="searchnumber" select="0"/>
<!--
Case Conversion
-->
  <xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyz'"/>
  <xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
  <xsl:variable name="lcasetext" select="translate($searchtext, $uppercase,
$lowercase)"/>
  <xsl:variable name="UCASETEXT" select="translate($searchtext, $lowercase,
$uppercase)"/>
  <xsl:variable name="ProperText"
select="concat(translate(substring($searchtext,1,1), $lowercase,
$uppercase),translate(substring($searchtext,2), $uppercase, $lowercase))"/>
<!--
Date Conversion from ISO8601 format
-->
  <xsl:template name="convertdate">
    <xsl:param name="date-time"/>
    <xsl:variable name="date" select="substring-before($date-time,'T')"/>
    <xsl:variable name="time" select="substring-after($date-time,'T')"/>
    <xsl:variable name="year" select="substring-before($date,'-')"/>
    <xsl:variable name="month"
select="substring-before(substring-after($date,'-'),'-')"/>
    <xsl:variable name="day"
select="substring-after(substring-after($date,'-'),'-')"/>
    <xsl:variable name="hour" select="substring-before($time,':')"/>
    <xsl:variable name="minute"
select="substring-before(substring-after($time,':'),':')"/>
    <xsl:variable name="second"
select="substring-after(substring-after($time,'-'),'-')"/>
    <xsl:variable name="entrydate" select="concat($month,'/',$day,'/',$year,'
',$hour,':',$minute)"/>
    <xsl:value-of select="$entrydate"/>
  </xsl:template>
<!--
Search and Sort Templates
-->
  <xsl:template name="textsearch">
    <xsl:for-each select="record[*[name() = $searchfield][contains(.,
$ProperText) or contains(., $UCASETEXT) or contains(., $lcasetext)]]">
      <xsl:sort select="*[name()=$sortbyfield]" order="{$sortorder}"/>
      <xsl:call-template name="resulttable"/>
    </xsl:for-each>
  </xsl:template>
  <xsl:template name="numbersearch">
    <xsl:for-each select="record[*[name() = $searchfield][contains(.,
$searchtext)]]">
      <xsl:sort select="*[name()=$sortbyfield]" data-type="number"
order="{$sortorder}"/>
      <xsl:call-template name="resulttable"/>
    </xsl:for-each>
  </xsl:template>
  <xsl:template name="datesort">
    <xsl:for-each select="record[*[name() = $searchfield][contains(.,
$searchtext)]]">
      <xsl:sort select="*[name()=$sortbyfield]" order="{$sortorder}"/>
      <xsl:call-template name="resulttable"/>
    </xsl:for-each>
  </xsl:template>
<!--
Output results of Search and Sort Templates
Clicking on Field1 executes a function in parameter.asp to launch another XSL
stylesheet
to display only the contents of that record.
-->
  <xsl:template name="resulttable">
    <tr>
      <td class="clsField1">
        <a><xsl:attribute
name="href">parameter.asp?mode=revdetail&amp;path=/path/record[idx="<xsl:valu
e-of select="idx"/>"]</xsl:attribute><xsl:value-of select="Field1"/></a>
      </td>
      <td class="clsField2">
        <xsl:value-of select="Field2"/>
      </td>
      <td class="clsDate">
        <xsl:call-template name="convertdate">
          <xsl:with-param name="date-time" select="dtmField"/>
        </xsl:call-template>
      </td>
    </tr>
  </xsl:template>
<!--
Navigation Menus -->
  <xsl:template name="linksmenu">
    <div id="header">
      <ul>
        <li>
         <!-- View 50 records at a time in a browse table -->
          <a>
            <xsl:attribute
name="href">parameter.asp?mode=review&amp;first=1&amp;last=50</xsl:attribute>
Review Records
          </a>
        </li>
        <li>
          <!-- Go back to the search parameter input form -->
          <a>
            <xsl:attribute
name="href">parameter.asp?mode=find</xsl:attribute>Search Records
          </a>
        </li>
      </ul>
    </div>
  </xsl:template>

  <xsl:template match="record">
    <html xmlns="http://www.w3.org/1999/xhtml";>
      <head>
        <link rel="stylesheet" type="text/css" href="record.css"/>
        <title> Search / Review Results </title>
      </head>
      <body>
        <p class="title"> Search / Review Results </p>
        <span class="tan">
          <xsl:call-template name="linksmenu"/>
          <p class="toptext"> Select a Record by clicking Field 1 to view the
Record's details. </p>
          <p>
            <table class="brwstable">
              <tr>
                <th> Field1 </th>
                <th> Field2 </th>
                <th> Date </th>
              </tr>
              <xsl:choose>
                <xsl:when test="$sortbydate = 1">
                  <xsl:call-template name="datesort"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:if test="$searchnumber = 0">
                    <xsl:call-template name="textsearch"/>
                  </xsl:if>
                  <xsl:if test="$searchnumber = 1">
                    <xsl:call-template name="numbersearch"/>
                  </xsl:if>
                </xsl:otherwise>
              </xsl:choose>
            </table>
          </p>
        </span>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

Thanks,
Russ Lewis

Current Thread