带有列表的C#中的自定义属性只需要访问每个项目的列表

时间:2012-05-01 17:30:28

标签: c# asp.net xml

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

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

    }

现在,当我尝试使用下面的代码访问它时,我没有得到我期望的输出。因此,这是我需要帮助的地方。 Sample 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>

输出:

你喜欢什么?

蛋糕

蛋糕

蛋糕

2 个答案:

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

答案 1 :(得分: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功能通过每个问题停止并绘制正确的控件

亲切的问候Roxas 我希望这有帮助