0

我有一个名为 Questions 的自定义属性,代码如下。

public class Questions
{
    private List<Question> _q = new List<Question>();

    public List<Question> Question
    {
        get { return _q; }
    } 
}

public class Question
{
    public string Text { get; set; }
    public string Name { get; set; }
    public string Type { get; set; }
    public string Answer { get; set; }
    private List<string> _Options = new List<string>(); 

    public List<string> Option {
      get { return _Options; }
    }

}

然后我用下面的代码填充属性

    XmlDocument doc = new XmlDocument();
    Question q = new Question();
    Questions qs = new Questions();
    doc.Load(string.Format(@"questions.xml"));
    XmlNodeList list = doc.SelectNodes("/questions/question");
    foreach (XmlNode node in list)
    {

            q.Text = node.SelectSingleNode("text").InnerText;
            q.Type = node.SelectSingleNode("type").InnerText;
            q.Name = node.SelectSingleNode("name").InnerText;
            XmlNodeList options = doc.SelectNodes("/questions/question/options");
            foreach (XmlNode option in options)
            {
                q.Option.Add(option.SelectSingleNode("option").InnerText);
            }
            load.Visible = false;
            qa.Visible = true;

            qs.Question.Add(q);
            DisplayQuestion(qs);

    }

现在,当我尝试使用下面的代码访问它时,我没有得到我期望的输出。因此,这就是我需要帮助的地方。示例 XML 位于底部

                Label1.Text = q.Question[CurrentQ].Text;
                for (int i = 0; i < q.Question[CurrentQ].Option.Count; i++)
                {
                    CheckBoxList1.Items.Add(q.Question[CurrentQ].Option[i]);
                }

XML:

<?xml version="1.0"?>
<questions>
  <question>
    <num>1</num>
    <type>radio</type>
    <text>Do you like cake?</text>
    <options>
      <option>Yes</option>
      <option>No</option>
      <option>Sometimes</option>
    </options>
    <name>cake</name>
  </question>
  <question>
    <num>2</num>
    <type>dropdown</type>
    <text>Do you like TV?</text>
    <options>
      <option>Yes</option>
      <option>No</option>
      <option>Sometimes</option>
    </options>
    <name>tv</name>
  </question>
  <question>
    <num>3</num>
    <type>checkbox</type>
    <text>What do you like?</text>
    <options>
      <option>Cake</option>
      <option>TV</option>
      <option>Flipper Reruns</option>
    </options>
    <name>flipper</name>
  </question>
</questions>

和输出:

你喜欢什么?

是的

是的

蛋糕

是的

是的

蛋糕

是的

是的

蛋糕

4

2 回答 2

2

您正在选择选项节点,而不是循环内部的doc当前节点。node

这个表达

doc.SelectNodes("/questions/question/options"); 

产量

<options>
  <option>Yes</option>
  <option>No</option>
  <option>Sometimes</option>
</options>
<options>
  <option>Yes</option>
  <option>No</option>
  <option>Sometimes</option>
</options>
<options>
  <option>Cake</option>
  <option>TV</option>
  <option>Flipper Reruns</option>
</options>

从这个选项组列表中,您总是选择每个组的第一个选项!

试试这个

node.SelectNodes("options/option");            

一切都放在一起

foreach (XmlNode node in list) {
    Question q = new Question(); // As RoXaS pointed out!
    ...
    XmlNodeList options = node.SelectNodes("options/option");
    foreach (XmlNode option in options) {
        q.Option.Add(option.InnerText);
    }
    ...
    qs.Question.Add(q);
}
于 2012-05-01T17:48:57.653 回答
2

答案很简单。错误在下面的代码中。

XmlDocument doc = new XmlDocument();
Question q = new Question();
Questions qs = new Questions();
doc.Load(string.Format(@"questions.xml"));
XmlNodeList list = doc.SelectNodes("/questions/question");
foreach (XmlNode node in list)
{

        q.Text = node.SelectSingleNode("text").InnerText;
        q.Type = node.SelectSingleNode("type").InnerText;
        q.Name = node.SelectSingleNode("name").InnerText;
        XmlNodeList options = doc.SelectNodes("/questions/question/options");
        foreach (XmlNode option in options)
        {
            q.Option.Add(option.SelectSingleNode("option").InnerText);
        }
        load.Visible = false;
        qa.Visible = true;

        qs.Question.Add(q);
        DisplayQuestion(qs);

}

C# 通过引用自动工作(意味着指向对象的指针而不是复制它)。所以在上面的声明中你声明 Question q = new Question(); 然后你填写它并将它添加到你的列表中并再次填写它。这意味着只有一个问题被实例化,因此结果都是一样的。

XmlDocument doc = new XmlDocument();

Questions qs = new Questions();
doc.Load(string.Format(@"questions.xml"));
XmlNodeList list = doc.SelectNodes("/questions/question");
foreach (XmlNode node in list)
{
        Question q = new Question(); // <--- Look here

        q.Text = node.SelectSingleNode("text").InnerText;
        q.Type = node.SelectSingleNode("type").InnerText;
        q.Name = node.SelectSingleNode("name").InnerText;
        XmlNodeList options = doc.SelectNodes("/questions/question/options");
        foreach (XmlNode option in options)
        {
            q.Option.Add(option.SelectSingleNode("option").InnerText);
        }
        load.Visible = false;
        qa.Visible = true;

        qs.Question.Add(q);


}
DisplayQuestion(qs); //<-- And here

这样,每当一个新问题被实例化并添加到列表中而不是被覆盖时。因为在您的 questionList 中,每个条目都只是指向您拥有的问题对象的一个​​实例的指针。

哦,为什么我把它DisplayQuestion(qs);放在那里?因为您不想一遍又一遍地绘制整个列表,对吗?

确保您的 Displayquestion 函数遍历每个问题并绘制正确的控件

亲切的问候罗哈斯,我希望这会有所帮助

于 2012-05-01T17:56:54.357 回答