使用Linq to XML(C#)尝试解析XML树

6
我希望能够在我的对象结构中反映出XML树,但我对LINQ to XML还是个初学者。
我有一个以下结构的XML:
<questions>
<question id="q1">
  <number>1</number>
  <text>some text11</text>
  <answers>
     <answer>
      <v>some text11</v>
    </answer>
    <answer>
      <v>some text11</v>
    </answer>
  </answers>
</question>
<question id="q2">
  <number>2</number>
  <text>some text2</text>

<answers>
    <answer>
      <v>some text22</v>
    </answer>
    <answer>
      <v>some text22</v>
    </answer>
  </answers>
</question>
<question id="q3">
  <number>3</number>
  <text>some text3</text>
  <answers>
    <answer>
      <v>some text33</v>
    </answer>
    <answer>
      <v>some text33</v>
    </answer>
    <answer>
      <v>some text33</v>
      <addDescription>some text333</addDescription>
      <textBox/>
    </answer>
  </answers>
</question>
</questions>

我有以下类:

public class Question
{
    public string text { get; set; }
    public IList<Anwser> anwsers = new List<Anwser>();
}

public class Anwser
{
    public string content { get; set; }
}

我曾经构建了下面这个错误的Linq查询:

        List<Question> questions = (from xml in xdoc.Element("survey").Elements("questions").Elements("question")
                                    select new Question()
                                               {
                                                   text = xml.Element("text").Value,
                                                   anwsers =
                                                       (from anwsers in
                                                            xdoc.Element("survey").Elements("questions").Elements("question").Elements(
                                                            "answers").Elements(
                                                            "answer")
                                                        select new Anwser()
                                                                   {
                                                                       content = anwsers.Element("v").Value
                                                                   }

                                                       ).ToList()
                                            }).ToList();

当然,这种方式可以让我每次都将所有问题的答案添加到每个列表中。如何解决?我可以想象这很简单,但我不知道怎么做 :)
提前感谢您!
3个回答

7

你的代码无法正常工作,因为你获取了所有答案元素,而没有根据它们来自的问题进行限制。你可以添加这个限制,或者将子查询基于问题元素本身而不是基于文档进行子查询。

List<Question> questions = (from question in xdoc.Element("survey").Element("questions").Elements("question")
         select new Question
         {
           text = question.Element("text").Value,
           anwsers = (from answer in question.Element("answers").Elements("answer")
                select new Anwser
                {
                  content = answer.Element("v").Value
                }).ToList()
         }).ToList();

使用 LINQ 解析 XML 是否比使用 XmlDocument 有任何优势? - B Faley

4

您很接近了。在选择新部件时,您不需要在类名后面加括号。此外,您要使用.Descendents()而不是.Elements()。另外一个部分是答案应该使用xml变量而不是回到原始文档,这样可以获得与问题相关的答案。

List<Question> questions = (from xml in xdoc.Descendants("question")
                                    select new Question
                                    {
                                        text = xml.Element("text").Value,
                                        answers =
                                            (from anwsers in xml.Descendants("answer")
                                             select new Answer
                                             {
                                                 Content = anwsers.Element("v").Value
                                             }

                                            ).ToList()
                                    }).ToList();

你的最后一句话是什么意思?创建一个对同一SelectIterator的新引用不会导致执行查询。 - Samuel
Samuel,要正确分配它,该行代码应该是这样的:List<Questions> myQuestions = questions.ToList()只有调用 .ToList() 或在 foreach 中使用查询才会执行。 - Alexander Kahoun
你应该删除那个语句。因为它暗示你必须执行List<Question> temp = (...).ToList(); 然后再执行List<Question> questions = temp; 才能使其生效。 - Samuel
好的,谢谢Samual提醒。我太习惯使用var并稍后获取值了,完全忘记了.ToList()已经在语句中了。 - Alexander Kahoun

1

问题似乎是你在内部选择中使用了xdoc,如果你将其更改为:

from answer in xml.Elements("answers").Elements("answer")

你应该没问题的。这应该可以工作,因为xml包含了question元素。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接