Thursday, February 10, 2011

Online Quiz Application Using XML and C#.


This article describes how to create a web quiz from the information in a Xml File and c#. 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. I developed this application using c# and xml data. I have seen several examples like this but I found all applications are in vb.net. so, I have taken some suggestion from that articles and I developed this application.

Please take one Xml file Named as Quiz.xml.

XML Data

Data for the online quiz is kept in an XML document named quiz.xml 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.
<?xml version="1.0" encoding="UTF-8"?>
<quiz xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
     <mchoice>
           <question>C# (C-Sharp) was developed by</question>
           <answer>Sun Microsystems</answer>
           <answer correct="yes">Microsoft</answer>
           <answer>Intel</answer>
           <answer>IBM</answer>
     </mchoice>
     <mchoice>
           <question>What is C# (C-Sharp)?</question>
           <answer>An Operating System </answer>
           <answer>An Programming Tool </answer>
           <answer correct="yes">An Programming Language </answer>
           <answer> None of these </answer>
     </mchoice>
     <mchoice>
           <question>C# (C-Sharp) belong to which framework ?</question>
           <answer correct="yes">.NET</answer>
           <answer>Java</answer>
           <answer>It does't belong to any framework</answer>
           <answer>None of these</answer>
     </mchoice>
     <mchoice>
           <question>What is CLR ?</question>
           <answer correct="yes">     Common Language Runtime</answer>
           <answer>Conventional Language Runtime</answer>
           <answer>Clarified Language Runtime</answer>
           <answer>Colloquial Language Runtime</answer>
     </mchoice>
     <mchoice>
           <question>Object Oriented Programming (OOP) is a style of programming in which your code is broken up into units, known as</question>
           <answer>objects</answer>
           <answer correct="yes">objects and classes</answer>
           <answer>classes</answer>
           <answer>objects or classes</answer>
     </mchoice>
     <mchoice>
           <question>There are, however, some advanced features of C++, such as __ that are not supported in .NET, and are therefore, not available in managed code.</question>
           <answer>Runtime classes</answer>
           <answer correct="yes">templates</answer>
           <answer>base classes</answer>
           <answer>multiple-document-interfaces</answer>
     </mchoice>
     <mchoice>
           <question>Using C# you can, for example, write a ___ web page?</question>
           <answer>dynamic</answer>
           <answer correct="yes">static</answer>
           <answer>standard</answer>
           <answer>classical</answer>
     </mchoice>
     <mchoice>
           <question>Using C# you can, for example, write ___ of a distributed application?</question>
           <answer>a core</answer>
           <answer>an array</answer>
           <answer>a structure</answer>
           <answer correct="yes">a component</answer>
     </mchoice>
<mchoice>
            <question>  What actually manages your code ?</question>
            <answer>JIT</answer>
            <answer correct="yes">CTS</answer>
            <answer >CLR</answer>
            <answer>CLS</answer>
      </mchoice>
      <mchoice>
            <question>When the . NET runtime loads and runs code, this is the language that it expects to find the code in.</question>
            <answer>Intermediate Language</answer>
            <answer>Common Type System</answer>
            <answer correct="yes">Just-in-Time Compilation</answer>
            <answer>Globally Unique IDentifiers</answer>
      </mchoice>
      <mchoice>
            <question>  When you compile managed code, the ____ actually emits IL.</question>
            <answer>debugger</answer>
            <answer>collector</answer>
            <answer correct="yes">translator</answer>
            <answer>compiler</answer>
      </mchoice>
      <mchoice>
            <question>  ____ this is a minimum set of standards that guarantees that code can be accessed from any language.</question>
            <answer correct="yes">Common Type System</answer>
            <answer>Common Language Specification</answer>
            <answer >Just-in-Time Compilation</answer>
            <answer>The .NET Runtime</answer>
      </mchoice>
      <mchoice>
            <question>Common Language Specification: This is a minimum set of standards that guarantees that code can be accessed from any</question>
            <answer >compiler</answer>
            <answer>stage</answer>
            <answer correct="yes">application</answer>
            <answer>language</answer>
      </mchoice>
      <mchoice>
            <question>Just-in-Time (JIT) Compilation: This is the term for the process of performing the ___ stage of compilation from IL into native machine code.</question>
            <answer correct="yes">intermediate</answer>
            <answer>beginning</answer>
            <answer >final</answer>
            <answer>whole</answer>
      </mchoice>
      <mchoice>
            <question>The function call generated by a non-OOP compiler causes what is called ___ binding</question>
            <answer>weak</answer>
            <answer correct="yes">strong</answer>
            <answer>early</answer>
            <answer>late</answer>
      </mchoice>
      <mchoice>
            <question>You create a string reference:</question>
            <answer>string {s};</answer>
            <answer>string [s];</answer>
            <answer>string (s);</answer>
            <answer correct="yes">string s;</answer>
      </mchoice>
      <mchoice>
            <question>  When you create a reference, you want to connect it with a new object. You do so, in general, with the</question>
            <answer>single quote</answer>
            <answer>double quote</answer>
            <answer correct="yes">round brackets</answer>
            <answer >new keyword</answer>
      </mchoice>
      <mchoice>
            <question>There are six different places to store data. This is a general-purpose pool of memory (also in the RAM area) where all C# objects live.</question>
            <answer>Registers</answer>
            <answer>The heap</answer>
            <answer >Static storage</answer>
            <answer correct="yes">The stack</answer>
      </mchoice>
</quiz>
The user interface will allow application users to click on the "Start Quiz" button to start the quiz. The quiz will have 20 questions and each question may have more or one answers. The question with single answer should have radio boxes to select an answer and the questions with multiple choices should have check boxes to select the answers.
In the end of the quiz, the results will be displayed to the user by percentage of correct answers and total questions. For example, if a user answers 16 questions correctly, he should see his result as 80%.

Then take one aspx page named as Default.aspx:
Write the following code in aspx page.
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Online Quiz</title>
<style>
body {
  font-size: 11px;
  font-family: verdana;
  color:#000000;
  background-color:#EEE;
}
.tableborder
{
     border: 1px dotted #99CC33;
}
.whitetable
{
     color: #000000;
     background-color: #ffffff;
     font-size: 11px;
     padding: 6px;
     font-family: Verdana;
}
.whitetable td
{
     font-size: 11px;
     font-family: Verdana;
}
tr.heading
{
    padding: 6px 0px 0px 6px;
     background: #EBF3FB;
     border: 1px solid #ACE;
}
 .button
 {
       font-family: Verdana;
       font-size: 11px;
       font-weight: normal;
       list-style-type: none;
       border: 1px solid #cccccc;
       background-color: #F0F0EB;
       color: #000;
       height: 24px;
       cursor :pointer ;
       background-image: url(background.jpg);
}
</style>
</head>
<body>
<span id="QuizScreen" runat="server">
<form id="Form1" runat="server">
  <table  bgcolor="#ffffff" border="0" cellpadding="3" cellspacing="0" class="tableborder" align="center" width="80%">
                    <tr>
                        <td align="left" colspan="2"  bgcolor="#95c03f">
                            <strong><span>C# Quiz</span></strong></td>
                    </tr>
                    <tr>
                        <td align="left" colspan="2" style="border: 1px solid #ACE;">
                     <asp:label id="lblQuestion" runat="server" Font-Bold="True" ForeColor="SteelBlue" /></td>
                    </tr>
            <tr>
                <td align="left" colspan="2" style="border-right: #ace 1px solid; border-top: #ace 1px solid; border-left: #ace 1px solid; border-bottom: #ace 1px solid">
      <asp:radiobuttonlist
          id="rblAnswer"
            RepeatDirection="vertical"
            TextAlign="right"
            RepeatLayout="table"
            runat="server" />
       <asp:requiredfieldvalidator ID="Requiredfieldvalidator1"
            ControlToValidate="rblAnswer"
            ErrorMessage="Please pick an answer!"
            runat="server" /></td>
            </tr>
            <tr>
                <td align="left" colspan="2" style="border-right: #ace 1px solid; border-top: #ace 1px solid; border-left: #ace 1px solid; border-bottom: #ace 1px solid">
      <asp:button id="btnSubmit"  CssClass="button" text="  Next  " onClick="btnSubmit_Click" runat="server" /></td>
            </tr>
            <tr>
                <td align="left" colspan="1" >
                    Total
                    <asp:label id="lblTotalQuestion" runat="server" />&nbsp; Questions</td>
                <td align="right" >
                    Time Spent
                    <asp:label id="lblTimeSpent" runat="server" /></td>
            </tr>
      <tr>
          <td align="left" colspan="1">
          </td>
          <td align="right">
    <asp:TextBox ID="txtCorrectAnswer" runat="server" Visible="False"></asp:TextBox></td>
      </tr>
             
                </table>
</form>
</span>
<span id="ResultScreen" runat="server">
<asp:label id="lblResult" runat="server" /> 
</span>
</body>
</html>
In code behind Default.aspx.cs:
This is coding part. Here I used  view state for maintaining  the state of all correct answers of questions and total answers selected by users etc...,please add System.Xml name space to your code behind  page.
XmlDocument xDoc = new XmlDocument();
    int intTotalQuestion;
    int intQuestionNo = 1;
    int intScore;
    DateTime startTime=DateTime.Now;
    ArrayList arrAnswerHistory = new ArrayList();
    ArrayList arrCorrectAnswers = new ArrayList();
    protected void Page_Load(object sender, EventArgs e)
    {
        //Load xml data
        xDoc.Load("E:/Projects/Csharpxmlquiz/Quiz.xml");

        //Start a new quiz?
        if (!Page.IsPostBack)
        {

            //Yes! Count total question
            intTotalQuestion = xDoc.SelectNodes("/quiz/mchoice").Count;

            //Record start time
            ViewState["StartTime"] = DateTime.Now;

            ShowQuestion(intQuestionNo);
        }
    }
    public void ShowQuestion(int intQuestionNo)
    {
        XmlNodeList xNodeList =default(XmlNodeList);
        XmlNode node;
        string strXPath = null;
        int i = 0;
        TimeSpan tsTimeSpent = default(TimeSpan);

        strXPath = "/quiz/mchoice[" + intQuestionNo.ToString() + "]";

        //Extract question
        lblQuestion.Text = intQuestionNo.ToString() + ". " + xDoc.SelectSingleNode(strXPath + "/question").InnerXml;

        //Extract answers
        xNodeList = xDoc.SelectNodes(strXPath + "/answer");

        //Clear previous listitems
        rblAnswer.Items.Clear();

        for (i = 0; i <= xNodeList.Count - 1; i++)
        {

            //Add item to radiobuttonlist
            rblAnswer.Items.Add(new ListItem(xNodeList.Item(i).InnerText));

            //Extract correct answer
           node = xNodeList.Item(i).Attributes.GetNamedItem("correct");
            if ((node != null))
            {
                if (node.Value == "yes")
                {
                    txtCorrectAnswer.Text = xNodeList.Item(i).InnerText;
                    arrCorrectAnswers.Add(xNodeList.Item(i).InnerText);
                }
            }
        }

        //Output Total Question
        lblTotalQuestion.Text = intTotalQuestion.ToString();

        //Output Time Spent
        tsTimeSpent = DateTime.Now.Subtract((DateTime)ViewState["StartTime"]);
        lblTimeSpent.Text = tsTimeSpent.Minutes.ToString() + ":" + tsTimeSpent.Seconds.ToString();

        //Store essential data to viewstate
        ViewState["TotalQuestion"] = intTotalQuestion;
        ViewState["Score"] = intScore;
        ViewState["QuestionNo"] = intQuestionNo;
        ViewState["AnswerHistory"] = arrAnswerHistory;
        ViewState["CorrectAnswers"] = arrCorrectAnswers;
    }

    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        //Retrieve essential variables from state bag
        intTotalQuestion =Convert.ToInt32( ViewState["TotalQuestion"]);
        intQuestionNo = Convert.ToInt32(ViewState["QuestionNo"]);
        intScore =Convert.ToInt32( ViewState["Score"]);
        arrAnswerHistory = (ArrayList)ViewState["AnswerHistory"];
        arrCorrectAnswers = (ArrayList)ViewState["CorrectAnswers"];
        //Correct answer?
        if (rblAnswer.SelectedItem.Text == txtCorrectAnswer.Text)
        {
            intScore += 1;
            arrAnswerHistory.Add(null);
        }
        else
        {
            arrAnswerHistory.Add(rblAnswer.SelectedItem.Text);
        }

        //End of quiz?
        if (intQuestionNo == intTotalQuestion)
        {

            //Yes! Show the result...
            QuizScreen.Visible = false;
            ResultScreen.Visible = true;
            //Render result screen

            ShowResult();
        }
        else
        {

            //Not yet! Show another question...
            QuizScreen.Visible = true;
            ResultScreen.Visible = false;
            intQuestionNo += 1;

            //Render next question
            ShowQuestion(intQuestionNo);
        }
    }
    public void ShowResult()
    {
        string strResult = null;
        int i ;
        string strXPath = null;
        TimeSpan tsTimeSpent = default(TimeSpan);
        tsTimeSpent = DateTime.Now.Subtract((DateTime)ViewState["StartTime"]);
        strResult = "<center>";
        strResult += "<h3>Quiz Result</h3>";
        strResult += "<p>Points: " + intScore.ToString() + " of " + intTotalQuestion.ToString();
        strResult += "<p>Your Competency: " + (intScore * 100 / intTotalQuestion).ToString() + "%";
        strResult += "<p>Time Spent: " + tsTimeSpent.Minutes.ToString() + ":" + tsTimeSpent.Seconds.ToString();
        strResult += "</center>";

        strResult += "<h3>Scrolldown to review your answers:</h3>";
        for (i = 1; i <= intTotalQuestion; i++)
        {
            strXPath = "/quiz/mchoice[" + i + "]";
            strResult += "<b>" + i.ToString() + ". " + xDoc.SelectNodes(strXPath + "/question").Item(0).InnerXml + "</b><br>";
            if (arrAnswerHistory[i-1] == null)
            {
                strResult += "<b>You answered: </b> " + arrCorrectAnswers[i - 1] + "<font color=\"green\"><b> (Correct)</b></font><br>"+"<br>";
            }
            else
            {
                strResult += "<b>You answered: </b> " + arrAnswerHistory[i - 1] + "<font color=\"red\"><b>(Wrong)</b></font><br>";
                strResult += "<font color=\"green\"><b>CorrectAnswer: </b></font>" + arrCorrectAnswers[i - 1] + "<br><br>";
            }
        }

        lblResult.Text = strResult;
    }

Conclusion:
I hope this application is very useful .

No comments:

Post a Comment