2016-07-01 55 views
0

我在C#中創建了一個測驗作爲控制檯應用程序。C#將XML元素讀取到2個單獨的列表中

我有一個XML文件,其中包含a)問題b)答案和c)不正確的答案。

我可以從我的XML文件中讀取問題。

但是我無法弄清楚我需要爲每個隨機生成的閱讀問題關聯不正確和正確的答案。

這是我的XML文件的副本。

<?xml version="1.0" encoding="utf-8"?> 
<Question xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <theQuestion>How many players in a football team?</theQuestion> 
    <answerA>12</answerA> 
    <answerB>10</answerB> 
    <answerC>20</answerC> 
    <answerD>11</answerD> 
    <correctAnswer>11</correctAnswer> 
    <theQuestion>How many minutes in a football game?</theQuestion> 
    <answerA>90</answerA> 
    <answerB>45</answerB> 
    <answerC>60</answerC> 
    <answerD>77</answerD> 
    <correctAnswer>90</correctAnswer> 
</Question> 

這裏是我的代碼部分:

ProcessData data = new ProcessData(); 

    //load questions from XML file and store in list 
    var questions = data.LoadQuizQuestions(); 

    //create a question object 
    Question q = new Question(); 

    //get a question randomly generated from questions list 
    int index = new Random().Next(questions.Count); 

    //display the randomly generated question 
    Console.WriteLine(questions[index]); 

    Console.ReadLine(); 

這裏是我的LoadQuizQuestions()

public List<string> LoadQuizQuestions() 
    { 
     //create empty list to store quiz questions read in from file 
     List<string> questions = new List<string>(); 

     //load questions from file into list 
     questions = 
     XDocument.Load(@"C:\Development\Learning\Files\qsFile.xml").Descendants("theQuestion").Select(o => o.Value).ToList(); 

     //return list of questions 
     return questions; 
    } 

我想,當每次隨機抽題顯示相應的回答這個問題也會顯示,並且「正確答案」被讀入一個變量,我可以檢查用戶輸入。

請幫助我瞭解,我知道我靠近釘這個:-)

謝謝

+0

更好地展示您的c OQ for LoadQuizQuestions – ilans

+0

爲什麼不使用xmlnode來查找答案狀態 – Developer

+0

ilans-LoadQuizQuestions只是從XML文件中只讀取問題 – xirokx

回答

0
  1. 讀取XML爲List<Question>收集
  2. 選擇一個隨機項
    1. 顯示問題和選項
    2. 詢問用戶輸入
    3. 比較用戶輸入正確答案
  3. 利潤

編輯:你的XML輸入處理您的數據連續,不分層;當您嘗試閱讀問題時,這會導致潛在的問題。

你應該考慮的結構是這樣的:

<Questions> 
    <Question> 
     <Title>How many players in a football team?</Title> 
     <Options> 
      <Option>12</Option> 
      <Option>10</Option> 
      <Option>20</Option> 
      <Option IsCorrect='true'>11</Option> 
     </Options> 
    </Question> 
    <Question> 
     <Title>How many minutes in a football game?</Title> 
     <Options> 
      <Option IsCorrect='true'>90</Option> 
      <Option>45</Option> 
      <Option>60</Option> 
      <Option>77</Option> 
     </Options> 
    </Question> 
</Questions> 

這將使易於人工讀取XML,或直接deserialising它變成一個List<Question>集合。

如果是a正確答案,我做出了保留選項的決定,因爲這可以靈活地適應多個正確的答案。

class Question 
{ 
    public string Title   { get; private set; } 
    public List<Option> Options { get; private set; } 

    public Question() 
    { 
    } 

    public Question(XmlElement question) : this() 
    { 
     this.Title = question["Title"].InnerText; 
     this.Options = question.SelectNodes("Options/Option") 
      .OfType<XmlElement>() 
      .Select(option => new Option(option)) 
      .ToList(); 
    } 
} 

沒什麼大不了的位置:我們剛剛看了一個XmlElement並委託給Option類的項目反序列化。

class Option 
{ 
    public string Title   { get; private set; } 
    public bool IsCorrect  { get; private set; } 

    public Option() 
    { 
    } 

    public Option(XmlElement option) : this() 
    { 
     this.Title = option.InnerText; 
     this.IsCorrect = option.GetAttribute("IsCorrect") == "true"; 
    } 
} 

相同的交易。

採用這種結構,可以做這樣的事情:

var xml = new XmlDocument(); 
    xml.LoadXml(@"..."); 

var random = new Random(); 
var questions = xml.SelectNodes("//Question") 
    .OfType<XmlElement>() 
    .Select (question => new Question(question)) 
    .OrderBy(question => random.Next()) 
    .ToList(); 

foreach (var question in questions) 
{ 
    Console.ForegroundColor = ConsoleColor.White; 
    Console.WriteLine(question.Title); 
    foreach (var option in question.Options) 
    { 
     Console.ForegroundColor = ConsoleColor.Gray; 
     Console.WriteLine("\t{0}", option.Title); 
    } 
    Console.Write("Choose the right option: "); 
    var answer = Console.ReadLine(); 

    if (question.Options.Any(option => 
     option.IsCorrect && answer.Equals(option.Title, 
      StringComparison.InvariantCultureIgnoreCase))) 
    { 
     Console.ForegroundColor = ConsoleColor.Green; 
     Console.WriteLine("YOU HAVE CHOSEN... WISELY."); 
    } 
    else 
    { 
     Console.ForegroundColor = ConsoleColor.Red; 
     Console.WriteLine("You have chosen poorly!"); 
    } 
} 
+0

我只能從XML文件中讀取一個元素 - 「theQuestion」而不是所有元素,即答案A-D和correctAnswer ...任何想法如何讀取所有問題並將它們放入單獨的Question對象中? – xirokx

+1

This works thank you – xirokx

0

如果你使用一個問題對象包含答案的列表,像這樣:

public class Question 
{ 
    public int ID { get; set; } 
    public string QuestionText { get; set; } 

    public List<Answer> Answers { get; set; } 

    public string AnswerText { get; set; } 
} 

public class Answer 
{ 
    public string ID { get; set; } 
    public string AnswerText { get; set; } 
} 

然後你可以閱讀問題和答案離散的對象,像下面的代碼(免責聲明:沒有測試,所以它可能需要調整工作)

public List<Question> GetQuestions(string xmlFile) 
    { 
     var questions = new List<Question>(); 

     var xDoc = XDocument.Load(xmlFile); 

     var questionNodes = xDoc.Descendants("theQuestion"); 

     foreach (var questionNode in questionNodes) 
     { 

      var question = new Question(); 
      question.QuestionText = questionNode.Value; 

      // do something like this for all the answers 
      var answer = new Answer(); 
      answer.ID = "A"; 
      var answerA = questionNode.Descendants("answerA").FirstOrDefault(); 
      if (answerA != null) 
       answer.AnswerText = answerA.Value; 

      question.Answers = new List<Answer>(); 
      question.Answers.Add(answer); 

      question.AnswerText = 
       questionNode.Descendants("correctAnswer").FirstOrDefault().Value; 
     } 

     return questions; 
    } 
} 

既然您在單個對象中有問題和答案,您可以顯示問題,答案,然後根據用戶輸入做一個字符串比較來檢查用戶的答案。

0

如果你可以改變你的XML結構我應該這樣做:

<?xml version="1.0" encoding="utf-8"?> 
<Questions> 
    <Question text="How many players in a football team?"> 
    <answerA>12</answerA> 
    <answerB>10</answerB> 
    <answerC>20</answerC> 
    <answerD>11</answerD> 
    <correctAnswer>11</correctAnswer> 
    </Question> 
    <Question text="How many minutes in a football game?"> 
    <answerA>90</answerA> 
    <answerB>45</answerB> 
    <answerC>60</answerC> 
    <answerD>77</answerD> 
    <correctAnswer>90</correctAnswer> 
    </Question> 
</Questions> 

然後反序列化使用這些類:

public class Questions 
{ 
    [XmlElement("Question")] 
    public List<Question> QuestionList { get; set; } = new List<Question>(); 
} 

public class Question 
{ 
    [XmlAttribute("text")] 
    public string Text { get; set; } 

    public string answerA { get; set; } 
    public string answerB { get; set; } 
    public string answerC { get; set; } 
    public string answerD { get; set; } 
    public string correctAnswer { get; set; } 
} 

而這種代碼:

string path = "yourxmlfile.xml"; 

XmlSerializer serializer = new XmlSerializer(typeof(Questions)); 

StreamReader reader = new StreamReader(path); 
var qs = (Questions)serializer.Deserialize(reader); 
reader.Close(); 
+0

[XmlElement(「Question」)]給了我一個錯誤「由於其受保護的級別,無法訪問構造函數XmlElement」,因此我無法使用您的解決方案反序列化文件。 – xirokx

+0

我測試了上面的代碼,它工作,所以你一定已經改變了一些東西。發佈你的代碼? –

+0

我可以在哪裏發佈代碼? – xirokx