Working with the WebSurvey Control's Results, Part 2By Steve Stchur
In Part 1 of this article we looked at the basics of the SurveyControl. In this second and final part, we'll take a deeper look at the XSL stylesheet responsible for rendering the XML answer file into appropriate HTML markup.
A Detailed Look at the SurveyResult Control's Stylesheet File
The SurveyResult control is really a pretty simple control. It works on the basis of simply using XSLT to transform an XML file into HTML suitable for display on a Web page. This transformation is completed by the SurveyResult on the survey, but you really don't even need ASP.NET to accomplish this. Most standards-compliant Web browsers can read an XSL file, and transform the XML associated with it into HTML. The obvious question then, regarding the SurveyResult control, is why did I even bother to create it, if HTML can be created from an XML file without the help of ASP.NET? There are two reasons. The first is that the AnswersFile generated by the WebSurvey control does not contain the questions to the survey. The SurveyFile contains those question, but of course, it does not contain the answers. In order to transform our XML, we need all of it in a single file. Part of what the SurveyResult control does is merge the two XML files together in memory in preparation for XSL transformation.
The second reason is that some browsers can't handle XSL transformation (or at least not very well). The .NET Framework, however, has some built in classes that handle this XSL transformation, and since it executes server-side, we can rid ourselves of worrying about client-side browser capabilities with regards to XSLT. The only caveat is to make sure we design our stylesheet to render HTML that is compatible with most browsers. XSLT can get very tricky (especially when you start considering looping, recursion, and other programming techniques familiar to most programmers). The problem is that, unlike Java, C++ / C#, Visual Basic, etc, XSLT is not an procedural language. Rather, it is a declarative and functional language, which is relative unknown to programmers of the aforementioned languages.
One of the key concepts I use in my stylesheet file is that of XSLT recursion. Because I have neither the knowledge nor the ability to explain this in great detail, I'd highly recommend checking out an article written by Jared Jackson of IBM: Use recursion effectively in XSL.
Below is the code from the
stylesheet.xsl file, with an explanation to follow:
Let's examine this stylesheet in a bit of detail. Since the stylesheet is an XML document in and of itself, it begins with an XML declaration:
Next, comes the declaration for the XSL stylesheet according to the W3C recommendation:
Following this, we have a line that indicates that our transformed output should be HTML, and that the HTML should be indented:
Next we have
<xsl:template match = "/">. The
<xsl:template> element contains rules
to apply when a specified node is matched. To match the whole document, we simply use
match = "/".
The next line defines the start of a loop. The
<xsl:for-each> element functions exactly as you would
guess. For every
//SurveyResult/Question node, the code between
</xsl:for-each> will be executed (i.e. once for every Question).
The first part of this loop creates a variable named,
type and tests to see if its value is
mcss (Multiple Choice, Single Selection). Note that when defining a variable, we simply name it in
name = "type"). However, when referring to the variable in subsequent code, we precede its name
$, as in
<xsl:if test = "$type = 'mcss'">.
If the question's type is not MCSS, we'll ignore it, because our stylesheet is not setup to handle any other type of
question. However, if it is an MCSS question, we'll begin generating the graphical results for that question.
The next step is to determine the question's
ID and then select it's "Statement" so we can display the
question before we generate any graphical results. We do this through the use of the
element. This functions a lot like
Response.Write() in ASP.NET.
Next, we want to determine the total number of results for this question (so we can calculate percentage). However, we want
to be sure we avoid any questions that may have been left blank (in the event that you didn't make them required in the
first place). To do this, we create a variable named,
null and do not assign any value to it. We then create
a variable named,
total whose value is equal to the number of answer for this question that are not null.
Now, we can begin generating the bars that represent each answer. I use a
<div> to accomplish this,
though it certainly could be done using tables, or images, or whatever. We've already got the total number of answers for
this question, but now we need to determine how many people pick each particular response. This is accomplished with
The first variable,
res, stands for "Result" and is defined by
select = ".". This means to
select the value of the current XML node in the
<xsl:for-each> loop. In this case, that means the
text associated with whichever
<Response> tag we're on in the loop. The next variable,
is the number of people who picked the current response as their answer for this question.
per variable stands for "Percent" and is simply the sum divided by the total multiplied by 100.
len variable stands for "Length" is the number of pixels long that the
will be to represent this response. I multiple by four (arbitrarily) just to make the bars a bit longer.
The next two lines actually "print" the
<div> to the screen along the various attributes that define it
(color, border, size, etc). The
<xsl:for-each> loop then ends, and I display the total number of
results for this question using the
Finally, I write a simple
<hr/> tag (Horizontal Rule) just to separate the results of each question.
If you weren't confused by the above explanation, you should feel very good about yourself. I got confused just writing it because, let's face it, XSLT is not always simple. The stylesheet I've provided for you should give you a good start for using the SurveyResult control, but don't be afraid to research XSLT and try modifying the file to suit your needs. There are endless possibilities beyond what I have developed to gussy up the results page, and I'd love to see what you can come up with.
Feel free to email your comment, questions, suggestions, or stylesheet files at firstname.lastname@example.org.