Introduction
The idea to write an online quiz came up when I was looking for an XML
tutorial. I visited W3Schools.com and found not only the tutorial I was looking
for, but more interestingly was an online quiz. I took the 20-questions quiz
once, and hey! I felt great about it. I wonder why there are just few web sites
offering online quiz like that.
A quiz is a great way to test your knowledge. An online quiz is a great
addition to your web site that could keep your visitors glued for a few more
minutes.
Download the demo project and try it. It is a 10-question quiz to challenge
your knowledge about Australian geography. Don't worry! All data is kept in a
clear, human-readable XML document, so you could easily peek for answers.
The Script Explained
I will not go through a very detail discussion about the script, but rather
highlight several areas in the script. Once you get the whole idea about the
script, then it is easy to modify or extend the script to suit your
requirements.
Recursive Script
There is only one aspx script to do various tasks in the online quiz. It is a
recursive script: a script that 'calls' itself over and over again until a
certain condition is reached. Precisely, the script does not call itself, but
posts form data to itself. This process is known as post back.
As the script posts back to itself continuously over the duration of the
quiz, we could say that it has many states. The first state is to initialize
several essential variables, count the total question, and record the quiz
start time. Then, in the first and each following state, the script displays a
multiple choice question to challenge user (see the snapshot above). A user
answering the question will trigger onClick
event, forcing a
post-back, and move the script to the next state. In the next state, the script
will run a subroutine associated with the event to check the answer and display
the next multiple question. The recursive flow repeats again and again, until
the last question is processed, where at this point a result is displayed.
The following activity diagram represents the recursive flow of the online
quiz script.
Maintaining State
The online quiz script needs to maintain state of its variables. There are a
bunch of alternatives to do so. The most advanced way is to use the session
object, and the conventional way is to use hidden inputs or a QueryString. ASP.NET
introduces another alternative called 'state bag'. Unlike the session object, state
bag is not persisted over the whole user session, but is brought forward from
one page to another page just like hidden inputs and querystring. However, it is
superior to hidden inputs and QueryStrings, since it can accept more data types
and the content has been encoded into a single string and therefore is not easy to tamper with.
Storing value into state bag:
ViewState("TotalQuestion") = intTotalQuestion
Getting value from state bag:
intTotalQuestion = ViewState("TotalQuestion")
The following is a list of variables to be kept in the state bag:
Variable Name |
State Bag Name |
Data Type |
Comments |
intTotalQuestion |
TotalQuestion |
int |
Keeps the total question in the quiz. The value is populated
in the first state of the quiz and remains constants over the duration of
quiz. |
intScore |
Score |
int |
Keeps the number of correct answer. |
intQuestionNo |
QuestionNo |
int |
Holds the last question number the user attempted. |
arrAnswerHistory |
AnswerHistory |
arraylist of int |
Records answers in the quiz. It will record 0 (zero) if the
answer is correct, otherwise record the selectedindex of the radio buttons. |
(none) |
CorrectAnswer |
int |
Holds the correct answer of previous question. It is made
available in the next state when the answer is checked for correctness. |
(none) |
StartTime |
date |
Holds the start time of the quiz. It is used to calculate
the time spent in the quiz. |
XML Data
Data for the online quiz is kept in an XML document named quiz.xml,
which is validated using an XML schema named quiz.xsd. A valid XML
document consists of a root element called quiz
, which has at least one
element called mchoice
(short for multiple-choice). Each mchoice
element has one question
child element, and two or more answer
child elements. The answer element may have the correct
attribute with possible value of either yes
or no
. In
fact, you should supply the correct
attribute with a value of yes
to one of the
answers in the same mchoice
, otherwise there will be no correct answer for the
question.
quiz.xml:
="1.0" ="UTF-8"
<quiz xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="quiz.xsd">
<mchoice>
<question>What is the capital city of Australia ?</question>
<answer>Sydney</answer>
<answer correct="yes">Canberra</answer>
<answer>Melbourne</answer>
<answer>Gold Coast</answer>
</mchoice>
<mchoice>
<question>Which city has an extensive tram network?</question>
<answer>Sydney</answer>
<answer correct="yes">Melbourne</answer>
<answer>Adelaide</answer>
<answer>Ballarat</answer>
</mchoice>
</quiz>
It is possible to insert HTML tags within the XML data, therefore the quiz may contain decorated texts, images, links, etc. instead of plain text. Just make sure to enclose the HTML tags with CDATA
block, so the XML document is still valid. Look at the following example:
<mchoice>
<question><![CDATA[]]></question>
<answer>Kangaroo</answer>
<answer correct="yes">Penguin</answer>
<answer>Koala</answer>
<answer>Wombat</answer>
</mchoice>
quiz.xsd:
="1.0" ="UTF-8"
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="quiz">
<xs:complexType>
<xs:choice>
<xs:element name="mchoice" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="question" type="xs:string"/>
<xs:element name="answer" minOccurs="2" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="correct" use="optional">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="yes"/>
<xs:enumeration value="no"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
The online quiz script does not validate the XML document against the XML Schema
for several reasons. First, it is a resource intensive process, forcing
XMLTextReader
to go through each element and attribute in the XML document.
Second, we need to validate the XML document just once after it has been updated,
instead of every time we load the file. To validate the XML document, you could
write a separate aspx script or use a third-party tool and run them manually
every after you finish updating the XML document.
XML Document Object Model
XML Document Object Model (DOM) is a tree-like structure that represents
every node of an XML document based on the hierarchical relationship with its parent
nodes and child nodes. The DOM allows us to navigate and manipulate XML document
in more logical way.
To build an XML DOM, we use the XMLDocument
class. The XMLDocument
class itself extends the XMLNode
class, therefore many of its
properties and methods are inherited from XMLNode. While XMLNode's methods and
properties apply to a specific node in an XML document, methods and properties of
XMLDocument apply to the whole XML document.
The following code create an instance of XMLDocument and build XML DOM from quiz.xml:
Dim xDoc as XMLDocument = New XMLDocument()
xDoc.Load(Server.MapPath("quiz.xml"))
Addressing a specific node in the XML DOM is a bit tricky. We should navigate
our 'pointer' through the DOM starting from its root node. The following code
demonstrates how to address the first question of the first multiple choice:
Dim xNode as XMLNode
xNode = xDoc.DocumentElement
xNode = xNode.NextSibling
xNode = xNode.FirstChild
xNode = xNode.FirstChild
Response.Write("The question is: " & xNode.InnerHtml)
It is definitely a tedious task, particularly if you want to address nodes located at
a very low level in the hierarchy. Luckily, we can utilize the XPath
language to more directly
address a specific node or a group of nodes. If you are unfamiliar with XPath, it
will be briefly explained in the next section.
The SelectNodes
method of the XMLNode and XMLDocument class' accepts an XPath string and returns a collection of XMLNode objects, called
XMLNodeList
. Another method, SelectSingleNode
, does just the
same thing but return only a single XMLNode object.
Dim xNodeList As XMLNodeList
Dim i as Integer
xNodeList = xDoc.SelectNodes("/quiz/mchoice[1]/answer")
For i = 0 to xNodeList.Count-1
Response.Write("<p>" & xNodeList.Item(i).InnerHtml)
Next
Dim xNode as XMLNode
xNode = xDoc.SelectSingleNode("/quiz/mchoice[1]/question")
Response.Write("The question is: " & xNode.InnerHtml)
XPath
XPath is a language to address specific nodes in an XML document. It could address a
single node or a group of nodes by describing its hierarchy relationship in a
string, therefore it is often called an XPath string. If you are familiar with file path
or URL, then the concept of XPath is nothing new.
Read the XPath string from left to right and you will be able to figure out the
node it is addressing. Except for several conditions and functions, XPath is
actually easy to use. The following table demonstrates some usage of XPath
against quiz.xml:
XPath String |
Result |
/quiz |
Select the root node of XML including all elements it
contains. |
/quiz/mchoice |
Select all mchoice child elements of the quiz |
/quiz/mchoice[1] |
Select the first mchoice (multiple choice) child element of
the quiz |
/quiz/mchoice[1]/question |
Select all questions of the first multiple choice of the
quiz |
/quiz/mchoice[1]/answer[4] |
Select the fourth answer of the first multiple choice of the
quiz |
/quiz/mchoice[1]/answer[4]/@correct |
Select 'correct' attribute of the fourth answer of the first
multiple choice of the quiz |
XPath contains a lot more surprises. If you are interested enough to explore more,
check out the
XPath Tutorial at W3CSchools.
Conclusions
This article presented an online quiz as a tool to add interactivity to your web
site. It also explored several topics like recursive scripts, navigating and
manipulating XML documents using the XML DOM, a glimpse of the XPath language, and a brief discussion about state maintenance.
Links