C#将XML元素读入2个单独的列表

时间:2016-07-01 11:44:59

标签: c# xml

我在C#中创建一个测验作为控制台应用。

我有一个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;
   }

我希望在显示每个随机问题时,还会显示该问题的相关答案并且正确答案&#34;读入一个我可以检查用户输入的变量。

请帮助我理解我知道我接近这个: - )

谢谢

4 个答案:

答案 0 :(得分:0)

  1. 将xml读入List<Question>集合
  2. 选择一个随机项目
    1. 显示问题和选项
    2. 询问用户输入
    3. 将用户输入与正确答案进行比较
  3. 利润
  4. 编辑:您的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,或将其直接反序列化为List<Question>集合。

    我决定保留选项,如果它 正确答案,因为这可以灵活到多个正确的答案。

    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!");
        }
    }
    

答案 1 :(得分:0)

如果您使用包含答案列表的问题对象,请执行以下操作:

<root xmlns="aaa.com" xmlns:b="bbb.com" xmlns:c="ccc.com">
    <child>...</child>
    <a:child>...</a.child>
    <b:child>...</b.child>
</root>

然后你可以把问题和答案读成离散的对象,比如下面的代码(免责声明:没有测试这个,所以可能需要调整才能工作)

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; }
}

既然您在单个对象中有问题和答案,您可以显示问题,答案,然后根据用户输入进行字符串比较以检查用户的答案。

答案 2 :(得分:0)

您可以根据需要检查我的逻辑以获取值XMLNode

How to get node values in XML file using c#

答案 3 :(得分: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();