SiteExperts.com Logo Home | Community | Developer's Paradise | Jobs
User Groups | Site Tools | Site Information | Search

Inside Technique : XML-Based Survey Server : Core ASP Functions

The survey.inc file contains all of the functions for presenting and managing surveys. This file must be included into your ASP page. For example, if the survey.inc file is in the same folder as the ASP page:

<% Option Explicit %>
<!-- #include file="survey.inc" -->

The survey.inc file contains three functions for retrieving surveys, saving votes, and listing all surveys on the system. When you want to insert a survey into your page, you call the getSurvey function and output the results. This getSurvey function has two arguments, the unique ID that identifies the survey and the ID defining the rendering scheme you want to use. To output the survey with ID="1" with the vertical orientation style you call getSurveys as follows:

response.write(getSurvey(1,"vBanner"))

The getSurvey() function extracts both the survey and the XSL block based on the passed in identifiers. The returned XSL block is then applied to the survey and returned from the function:

function getSurvey(sID,sRender)
  Dim findNode, result, source, style, outputNode
  if sID="" then sID="1"
  if isempty(application("survey")) then
    loadSurveys
  end if
  if isempty(application("survey" & sID & sRender)) then
    set source = application("survey")
    set style = application("style")
    set findNode = source.selectSingleNode("surveylist/survey[id[. = """ & sID & """]]")
    if not findNode is nothing then
      set outputNode = style.selectSingleNode("xsl:stylesheet/render[@id=""" & sRender & """]")
      if not outputNode is nothing then
        result = findNode.transformNode(outputNode)
        application.lock
        application("survey" & sID) = result
        application.unlock
      else
        result = "ERROR - Bad Render ID"
      end if
    else
      result = "ERROR - Bad ID"
    end if
  else
    result = application("survey" & sID & sRender)
  end if
  getSurvey = result
end function

The function extracts the survey and applies it to the appropriate XSL block by executing queries against the XML. When examining the above function, notice the two calls to selectSingleNode. This method is used to locate the specific survey and rendering scheme. For example, the query that retrieves the survey with ID of "1" searches for the single survey node that contains the ID node with the value of "1":

surveylist/survey[id[. = "1"]]

Examining this query, the "/" is used to define the context we are searching in. The square brackets "[" are used to do deeper searches without switching the context. This query is looking for the survey node within the surveylist node that contains an id node of the value 1. By using the square brackets, we are specifying that we want the survey node returned even though we are searching the survey's contents. When the above query is run against our sample surveys, the following sub-tree is returned:

<survey voters="20">
  <id>1</id>
  <question>Do you program with ASP?</question>
  <answer votes="13">Yes</answer>
  <answer votes="7">No</answer>
</survey>

The rendering query works essentially the same way. The primary difference is we are matching the render node's ID attribute instead of an ID element. This is done using the "@" operator:

xsl:stylesheet/render[@id="vBanner"]

This returns the render element for the vBanner and provides access to the complete render sub-tree:

<render id="vbanner">
<TABLE BORDER="1" WIDTH="125" CELLSPACING="0">
  <TR><TD ALIGN="CENTER"> 
    <FORM>
      <xsl:value-of select="question"/><BR/>
      <INPUT TYPE="HIDDEN" NAME="ID">
        <xsl:attribute name="VALUE"><xsl:value-of select="id"/></xsl:attribute>
      </INPUT>
      <xsl:for-each select="answer">
        <P STYLE="margin:5px"><INPUT TYPE="SUBMIT" NAME="VOTE">
        </INPUT></P>
      </xsl:for-each>
    </FORM>
    </TD></TR>
  <TR><TD><FONT FACE="verdana,geneva,arial"><SMALL><SMALL>Survey Server from <A HREF="http://www.siteexperts.com">SiteExperts.com</A></SMALL></SMALL></FONT></TD></TR>
</TABLE>
</render>

Finally we execute the transformNode function with the returned XSL node against the survey. Since the survey's output is always the same there is no need to regenerate the output on every request. Therefore, to improve performance we cache the generated output in the application object. If you modify the XSL sheets to include dynamic information (eg., total votes, etc), you may need to modify our caching scheme.

In our next section, we show you how a user's vote is processed and how the results are rendered.