1

I have a XML with 3 questions 4 options each and answer. I would like to have one question to be selected in random and display it in the html div tag. Please help in doing this.

I;m getting the object instead of the value in the xml node.

<exam>
<sitescope>
    <q1>what is sitescope 1</q1>
    <q1a1>1</q1a1>
    <q1a2>2</q1a2>
    <q1a3>3</q1a3>
    <q1a4>4</q1a4>
    <q1ans>1</q1ans>
    <q2>what is sitescope 1</q2>
    <q2a1>1</q2a1>
    <q2a2>2</q2a2>
    <q2a3>3</q2a3>
    <q2a4>4</q2a4>
    <q2ans>1</q2ans>
    <q3>what is sitescope 1</q3>
    <q3a1>1</q3a1>
    <q3a2>2</q3a2>
    <q3a3>3</q3a3>
    <q3a4>4</q3a4>
    <q3ans>1</q3ans>
</sitescope>

This is the HTML page im using:

<html>
<script type="text/javascript">
function questions() {
    var request = new XMLHttpRequest();
    request.open("GET", "/questions.xml", false);
    request.send();
    var xml = request.responseXML;

    var qstn = xml.getElementsByTagName("q1").item(0).nodeValue;
    var qstnans1 = xml.getElementsByTagName("q1a1").item(0).nodeValue;
    var qstnans2 = xml.getElementsByTagName("q1a2").item(0).nodeValue;
    var qstnans3 = xml.getElementsByTagName("q1a3").item(0).nodeValue;
    var qstnans4 = xml.getElementsByTagName("q1a4").item(0).nodeValue;


    document.getElementById("q1").innerHTML = qstn;
    document.getElementById("q1a1").innerHTML = qstnans1;
    document.getElementById("q1a2").innerHTML = qstnans2;
    document.getElementById("q1a3").innerHTML = qstnans3;



</script>


<form>
    <div>
        <div>
            <div style="float: left;" id="qstn1"></div>
            <div id="q1"></div>
        </div>
        <br>
        <div>
            <input type="radio" name="1" style="float: left;">
            <div id="q1a1"></div>
        </div>
        <br>
        <div>
            <input type="radio" name="1" style="float: left;">
            <div id="q1a2"></div>
        </div>
        <br>
        <div>
            <input type="radio" name="1" style="float: left;">
            <div id="q1a3"></div>
        </div>
        <br>
        <div>
            <input type="radio" name="1" style="float: left;">
            <div id="q1a4"></div>
        </div>
    </div>

</form>
6
  • can you change the structure of the xml? like: <item><q></q><as><a></a><a></a><a></a><a></a></as></item><item><q></q><as><a></a><a></a><a></a><a></a></as></item> Commented Aug 20, 2013 at 11:34
  • yes can change that to that. Commented Aug 20, 2013 at 11:37
  • nope i don knw json. the function h() is not being triggered at all. Commented Aug 20, 2013 at 12:14
  • i'm trying to do it in json. it's prolly simpler. Commented Aug 20, 2013 at 12:25
  • you tested the json variante? Commented Aug 20, 2013 at 13:16

3 Answers 3

1

Here is a FULLY working code for the json way

which stores the answers into an array and prints them at the end.

  1. shuffle function
  2. caches the questions
  3. stores the answers
  4. adds and removes the unnecessary eventhandlers.
  5. prints out the result
  6. uses document fragment
  7. infinite questions
  8. infinite answers
  9. compatible with external libraries
  10. and the references are all defined on load

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Quiz</title>
<script>
(function(W){
var q,current=0,question,answers,btn,D,A=[];
function shuffleArray(d){for(var c=d.length-1;c>0;c--){var b=Math.floor(Math.random()*(c+1));var a=d[c];d[c]=d[b];d[b]=a}return d}
function ajax(a,b,c){c=new XMLHttpRequest;c.open('GET',a);c.onload=b;c.send()}
function set(){q=shuffleArray(JSON.parse(this.response));next()}
function next(){
 var a=q[current];
 question.innerText=a.question;
 var f=D.createDocumentFragment();
 for(var c=0,d;d=a.answers[c];++c){
  var g=D.createElement('input'),l=D.createElement('label');
  g.type='radio';g.name='a';g.value=d;  
  l.appendChild(g);l.appendChild(D.createTextNode(d));
  f.appendChild(l); 
 }
 btn.addEventListener('click',ok,false);
 answers.innerHTML='';
 answers.appendChild(f);
 current++;
}
function ok(){
 btn.removeEventListener('click',ok,false);var a=current-1;
 A[a]={'q':q[a].question,'a':answers.querySelector('input[type="radio"]:checked').value}
 if(current<q.length){next()}else{done()}
}
function done(){
 question.parentNode.removeChild(question);
 answers.parentNode.removeChild(answers);
 btn.parentNode.removeChild(btn);
 D.body.appendChild(D.createElement('pre')).innerText=JSON.stringify(A,null,' '); 
}
function init(){
 D=W.document;
 answers=D.getElementById('answers');
 question=D.getElementById('question');
 btn=D.getElementById('btn');
 ajax('exam.js',set);
}
W.addEventListener('load',init,false);
})(window)
</script>
</head>
<body>
<div id="question"></div>
<div id="answers"></div>
<button id="btn">OK</button>
</body>
</html>

json

[
 {
  "question":"what is a?",
  "answers":["a","b","c","d"]
 },
 {
  "question":"what is b?",
  "answers":["a","b","c","d"]
 },
 {
  "question":"what is c?",
  "answers":["a","b","c","d"]
 }
]
Sign up to request clarification or add additional context in comments.

Comments

0

So the xml is properly structured this way.

in the html i added the Fisher Yates Shuffle function as it's an exam and so it returns a more real number number vs just length*Math.random();

n contains the shuffled answers index.

the code is not finished ... it just shows the first random question.

xml

<?xml version="1.0" encoding="utf-8"?>
<exam>
<item>
<question>what is a?</question>
<answers>
 <answer>a</answer>
 <answer>b</answer>
 <answer>c</answer>
 <answer>d</answer>
</answers>
</item>
<item>
<question>what is b?</question>
<answers>
 <answer>a</answer>
 <answer>b</answer>
 <answer>c</answer>
 <answer>d</answer>
</answers>
</item>
<item>
<question>what is c?</question>
<answers>
 <answer>a</answer>
 <answer>b</answer>
 <answer>c</answer>
 <answer>d</answer>
</answers>
</item>
<item>
<question>what is d?</question>
<answers>
 <answer>a</answer>
 <answer>b</answer>
 <answer>c</answer>
 <answer>d</answer>
</answers>
</item>
</exam>

html

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<script>
function shuffleArray(d){for(var c=d.length-1;c>0;c--){var b=Math.floor(Math.random()*(c+1));var a=d[c];d[c]=d[b];d[b]=a}return d};
function x(a,b,c){ // Url, Callback, just a placeholder
 c=new XMLHttpRequest;
 c.open('GET',a);
 c.onload=b;
 c.send()
}
function h(){
 var i=this.responseXML.getElementsByTagName('item'),l=i.length,n=[];
 while(l--){n[l]=l};
 n=shuffleArray(n);
 document.getElementById('question').innerText=i[n[0]].getElementsByTagName('question')[0].textContent;
}
window.onload=function(){
x('exam.xml',h);
}
</script>
</head>
<body>
<div id="question"></div>
</body>
</html>

if you don't understand something just ask..

Comments

0

You should consider changing your xml structure to a more manageable one or use JSON as has been suggested. But, since I had time to kill

function displayQn(xml, qnIdx) {
  var prefix = 'q' + qnIdx;
  document.getElementById("q").innerHTML = xml.querySelector(prefix).textContent;
  for ( var i = 1; i < 5; i++ ) {
    document.getElementById('a' + i).innerHTML = xml.querySelector(prefix + 'a' + i).textContent;
  }
}
//...
var xml = request.responseXML;
var total = parseInt(xml.querySelector('sitescope').lastElementChild.tagName.replace(/q(\d+)ans/, '$1'), 10)
var qnIdx = Math.floor(Math.random() * total) + 1;
displayQn(xml, qnIdx);

JSFiddle Link: http://jsfiddle.net/UfQea/3/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.