2009-04-26 4 views
6

Я хотел бы, чтобы отразить дерево XML в моей структуре объекта, но я очень новичок в LINQ к XMLПопытка разобрать XML дерево с Linq для XML (C#)

У меня есть 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(); 

Конечно, таким образом я получаю каждый раз, когда все пользователи задают все вопросы, добавленные в каждый список. Как это решить? Я могу представить, что это просто, но я понятия не имею :)

Заранее спасибо!

ответ

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(); 
+0

Использование LINQ для анализа XML имеет какое-либо преимущество перед использованием 'XmlDocument'? – Meysam

1

Проблема, кажется, вы начинаете с XDoc в ваш внутренний выбор, если вы изменить его на:

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

Вы должны быть хорошо. Это должно работать, потому что xml содержит элемент вопроса.

4

Вы были очень близки. В выбранных новых частях вам не нужно() после имен классов. Также вы хотите использовать .Descendents() вместо .Elements(). Единственная другая часть - ответы должны использовать переменную xml var, не возвращаясь к исходному документу, это дает вам ответы, связанные с вопросом.

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(); 
+0

Что вы подразумеваете под последним заявлением? Создание новой ссылки на тот же SelectIterator не приведет к выполнению запроса. – Samuel

+0

Разный подход +1 –

+0

Samuel, чтобы назначить его правильно, строка будет выглядеть примерно так: List myQuestions = questions.ToList() Только вызывая .ToList() или используя запрос в foreach, он выполнит. –