2016-07-01 57 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