2010-04-08 4 views
4

Je me demandais s'il y avait un moyen d'obtenir une liste de résultats dans une liste avec linq à xml. Si je devais le code XML suivant par exemple:C# linq à xml à la liste

<?xml version="1.0"?> 
<Sports xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <SportPages> 
     <SportPage type="test"> 
      <LinkPage> 
       <IDList> 
        <string>1</string> 
        <string>2</string> 
       </IDList> 
      </LinkPage> 
     </SportPage> 
    </SportPages> 
</Sports> 

Comment pourrais-je obtenir une liste de chaînes de la idlist?

Je suis assez nouveau pour LINQ to XML, donc je viens d'essayer des choses, je suis actuellement à ce stade:

var IDs = from sportpage in xDoc.Descendants("SportPages").Descendants("SportPage") 
         where sportpage.Attribute("type").Value == "Karate" 
         select new 
         { 
          ID = sportpage.Element("LinkPage").Element("IDList").Elements("string") 
         }; 

Mais le var est chaotique à lire décemment. N'y a-t-il pas une façon que je pourrais juste obtenir une liste de ficelles de ceci?

Merci

Répondre

6

Cette requête fonctionne - testé et vérifié:

var ID2 = (from sportpage in xDoc.Descendants("SportPages").Descendants("SportPage") 
      where sportpage.Attribute("type").Value == "Karate" 
      select sportpage) 
      .Descendants("LinkPage") 
      .Descendants("IDList") 
      .Elements("string") 
      .Select(d => d.Value) 
      .ToList(); 

me donne une liste de deux chaînes, "1" et "2".

+1

Cela va jeter une exception null objet si vous avez déjà un élément 'SportPage' qui n'a pas d'attribut' type'. –

+0

l'a résolu, j'ai enlevé les descendants de LinkPage et les descendants de SportPages parce que, grâce à d'autres réponses, je me suis rendu compte qu'il autosearches :) Donc merci beaucoup à vous tous! – WtFudgE

2
var myStrings = xDoc.Descendants("SportPage") 
        .Where(d => d.Attribute("type").Value == "Karate") 
        .Descendants("IDList") 
        .Descendants("string") 
        .Select(d => d.Value); 

de voir votre chaîne:

xDoc.Descendants("SportPage") 
    .Descendants("IDList") 
    .Where(d => d.Attribute("type").Value == "Karate") 
    .Descendants("string") 
    .Select(d => d.Value) 
    .ToList() 
    .ForEach(Console.WriteLine); 
+1

mais vous négligez la condition 'sportpage.Attribute ("type") Valeur == "Karate"' –

1

Voulez-vous dire cela?

List<string> IDs = xDoc.Descendants("SportPages").Descendants("SportPage") 
    .Where(anySportPage => anySportpage.Attribute("type").Value == "Karate") 
    .Select(karateSportPage => karateSportpage.Element("LinkPage").Element("IDList").Elements("string")) 
    .ToList(); 
+0

je reçois. « Erreur: Impossible de convertir implicitement le type « System.Collections.Generic. Liste > 'à' System.Collections.Generic.List '" –

+0

Vous devez également faire attention avec vos majuscules et minuscules: par ex. cette déclaration ne fonctionne pas: '.Where (anySportPage => anySportpage.' - vous devez utiliser le même boîtier dans les deux cas !! 'anySportPage vs anySportpage' - pas identique! –

+0

Né de ne pas tester et en supposant que je savais ce qui est sorti du '.Elements()'. (Utiliser 'var IDs 'fonctionnerait, mais je n'ai jamais vraiment aimé' var'.) Merci pour les corrections, et pour avoir écrit une réponse correcte. :) – ANeves

0

Je pense que la raison pour laquelle vous trouvez le "var" chaotique est votre création du type anonyme avec le "nouveau" dans votre sélection. Si vous sélectionnez simplement l'élément que vous recherchez, le var ne sera pas un type anonyme.

par exemple.

select sportpage.Element("LinkPage").Element("IDList").Elements("string"); 

Cependant, ma préférence serait de le faire en utilisant le. notation comme ça.

List<string> ids = xDoc.Elements("SportPages").Elements("SportPage").Where(sportPage => sportPage.Attribute("type").Value == "Karate").Elements("LinkPage").Elements("IDList").Elements("string").Select(id => id.Value).ToList(); 
0

Le plus gros problème que vous avez eu est que vous n'avez pas saisi le .Value à partir de l'ensemble d'éléments renvoyé. Mais voici une autre façon de le faire.

var ids = from sportPage in xDoc.Descendants("SportPage") 
      let attrib = sportPage.Attribute("type") 
      where attrib != null 
      let type = attrib.Value 
      where !string.IsNullOrEmpty(type) 
       && type == "Karate" 
      from id in sportPage.Descendants("IDList").Elements() 
      select id.Value; 
+0

De cette façon, c'est plutôt paresseux. Si vous avez un schéma explicite, vous pouvez utiliser la même chose que dans votre exemple dans la question. Vous avez juste besoin d'ajouter un '.Value' à la fin de l'instruction dans votre select. –