2010-01-18 6 views
3

J'essaie d'extraire des informations d'un fichier XML dans un objet en utilisant LINQ to XML. Bien que je puisse renvoyer les attributs Id de document et de section, je ne peux pas accéder à l'élément Items pour chaque élément de section, il renvoie un IEnumerable de tous les éléments du document. Je sais que c'est correct car j'appelle Descendants mais j'ai du mal à le faire pour ne renvoyer que les éléments enfants de chaque élément de section. Quelqu'un peut-il aider?LINQ to XML Sélection d'éléments enfants

document XML

<root> 
<document id="1"> 
    <section id="1.1"> 
    <item id="1.1.1"></item> 
    <item id="1.1.2"></item> 
    <item id="1.1.3"></item> 
    </section> 
    <section id="1.2"> 
    <item id="1.2.1"></item> 
    <item id="1.2.2"></item> 
    </section> 
</document> 
</root> 

requête LINQ

XElement documentRoot = XElement.Load("document.xml"); 
var documents = (from docs in documentRoot.Descendants("document") 
       select new 
        { 
         Id = (string) docs.Attribute("id"), 
         Sections = docs.Elements("section"), 
         Items = docs.Elements("section").Elements("item") 
        }).ToList(); 

foreach(var doc in documents) 
{ 
    foreach(var section in doc.Sections) 
    { 
     Console.WriteLine("SectionId: " + section.Attribute("Id")); 
     foreach(var item in doc.Items) 
     { 
      Console.WriteLine("ItemId: " + section.Attribute("Id")); 
     } 
    } 
} 
+1

Je ne suis pas un peu clair quant à l'objectif. Votre objet anonyme est composé de l'ID du document, de toutes les sections du document et de tous les éléments de toutes les sections du document. Si vous essayez de reconstruire la hiérarchie XML en tant qu'objet anonyme, vous aurez besoin de plusieurs requêtes. Pourquoi ne pas simplement utiliser le XML dans ce cas? – womp

Répondre

6

Vous avez quelques petites fautes de frappe, sur l'attribut Id et à boucle d'article. Mais si vous essayez d'obtenir tous les éléments de section dans cette collection d'éléments, vous avez tort au niveau du design, car Items devrait être une propriété Section, et non Document (donc vous devrez interroger votre XML deux fois).

Ou, vous pouvez faire quelque chose comme:

var documents = 
    (from docs in documentRoot.Descendants("document") 
    select new 
    { 
     Id = (string) docs.Attribute("id"), 
     Sections = docs.Elements("section") 
    }).ToList(); 

foreach (var doc in documents) 
{ 
    foreach (var section in doc.Sections) 
    { 
     Console.WriteLine("SectionId: " + section.Attribute("id")); 
     foreach (var item in section.Elements("item")) 
     { 
      Console.WriteLine("ItemId: " + item.Attribute("id")); 
     } 
    } 
} 

Sortie:

 
SectionId: id="1.1" 
ItemId: id="1.1.1" 
ItemId: id="1.1.2" 
ItemId: id="1.1.3" 
SectionId: id="1.2" 
ItemId: id="1.2.1" 
ItemId: id="1.2.2" 
+0

Désolé pour les fautes de frappe, mais ne résout toujours pas le problème. Ce que j'essaye d'accomplir est que seulement les articles qui sont des enfants à chaque section sont retournés. – Cragly

+0

@Cragly, je viens de réécrire ma réponse, jetez un oeil –

+0

Excellent! fonctionne comme un charme. Une telle solution simple. Je n'aurais pas pu voir le bois pour les arbres aussi longtemps passé à regarder celui-ci. Homme bon. – Cragly

2

Voulez-vous une structure plane?!?! (De LINQPad)

XElement documentRoot = XElement.Parse (
@"<root> 
<document id='1'> 
    <section id='1.1'> 
    <item id='1.1.1'></item> 
    <item id='1.1.2'></item> 
    <item id='1.1.3'></item> 
    </section> 
    <section id='1.2'> 
    <item id='1.2.1'></item> 
    <item id='1.2.2'></item> 
    </section> 
</document> 
</root> 
"); 




var documents = (from docs in documentRoot.Descendants("section") 
       select new 
        { 
         SectionId = (string) docs.Attribute("id"), 
         Items = docs.Elements("item") 
        }); 
documents.Dump(); 

Cela donne 2 SectionId éléments qui containes XElement s avec des articles connexes.

+0

Merci pour la publication, mais ce que je voudrais, c'est pouvoir accéder à ces éléments XElements et les affecter à la propriété Items de l'objet afin que j'obtiens un IEnumerable d'éléments associés à sa section spécifique. – Cragly

+0

Pouvez-vous donner un exemple de la structure de données que vous aimeriez avoir. Pourquoi XElement au lieu d'un type?!?! – salgo60