2009-04-26 20 views
6

me gustaría reflejar el árbol XML en mi estructura del objeto, pero estoy absolutamente un principiante en LINQ to XMLintentar analizar árbol XML con LINQ to XML (C#)

tengo un XML con la siguiente estructura:

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

... y tengo siguientes clases:

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

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

... y tengo que construir un siguiente (mal) LINQ consulta:

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

Por supuesto, de esta manera obtengo cada vez todas las guías de todas las preguntas agregadas a cada lista. ¿Cómo resolver esto? Puedo imaginar que esto es simple, pero no tengo ni idea :)

¡Gracias de antemano!

Respuesta

7

Su código no funciona porque está recuperando todos los elementos de respuesta porque no los restringió según la pregunta de la que provenían. Puede agregar esta restricción o, en lugar de una subconsulta basada en el documento, puede hacer la subconsulta en función del elemento de pregunta en sí.

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

¿Usar 'LINQ' para analizar XML tiene alguna ventaja sobre el uso de' XmlDocument'? – Meysam

1

El problema parece ser que está comenzando con xdoc en su interior seleccione si tuviera que cambiarlo a:

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

que debe estar bien. Esto debería funcionar porque xml contiene el elemento pregunta.

4

Estabas muy cerca. En las nuevas partes selectas, no necesita() después de los nombres de las clases. También desea utilizar .Descendents() en lugar de .Elements(). La única otra parte era que las respuestas deberían estar utilizando la var xml que no regresa al documento original, esto le da las respuestas asociadas con la pregunta.

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

¿Qué quiere decir con su última declaración? Crear una nueva referencia al mismo SelectIterator no hará que ejecute la consulta. – Samuel

+0

Diferente enfoque +1 –

+0

Samuel, para asignarlo correctamente, la línea se vería así: List myQuestions = questions.ToList() Solo se ejecutará al invocar .ToList() o al utilizar la consulta en un foreach. –