2010-03-22 5 views
5

Je rencontre un problème lors de l'exécution d'une requête LINQ. J'ai ce code XML:Requête imbriquée Linq to XML

<devices> 
    <device id ="2142" name="data-switch-01"> 
    <interface id ="2148" description ="Po1"/> 
    </device> 
    <device id ="2302" name="data-switch-02"> 
    <interface id ="2354" description ="Po1"/> 
    <interface id ="2348" description ="Gi0/44" /> 
    </device> 
</devices> 

Et ce code:

var devices = from device in myXML.Descendants("device") 
       select new 
       { 
        ID = device.Attribute("id").Value, 
        Name = device.Attribute("name").Value, 
       }; 

foreach (var device in devices) 
{ 
    Device d = new Device(Convert.ToInt32(device.ID), device.Name); 

    var vIfs = from vIf in myXML.Descendants("device") 
        where Convert.ToInt32(vIf.Attribute("id").Value) == d.Id 
        select new 
        { 
         ID = vIf.Element("interface").Attribute("id").Value, 
         Description = vIf.Element("interface").Attribute("description").Value, 
        }; 
    foreach (var vIf in vIfs) 
    { 
     DeviceInterface di = new DeviceInterface(Convert.ToInt32(vIf.ID), vIf.Description); 
     d.Interfaces.Add(di); 
    } 

    lsDevices.Add(d); 
} 

Mon objet de l'appareil contient une liste de DeviceInterfaces que je dois remplir à partir du XML. Au moment où mon code ne remplit que la première interface, tous les suivants sont ignorés et je ne peux pas comprendre pourquoi.

J'aimerais aussi savoir si c'est la bonne façon de le faire. Les boucles foreach imbriquées semblent un peu en désordre me

Vive

Répondre

12
IEnumerable<Device> devices = 
    from device in myXML.Descendants("device") 
    select new Device(device.Attribute("id").Value, device.Attribute("name").Value) 
    { 
    Interfaces = (from interface in device.Elements("Interface") 
        select new DeviceInterface(
         interface.Attribute("id").Value, 
         interface.Attribute("description").Value) 
       ).ToList() //or Array as you prefer 
    } 

Le point fondamental est que vous faites une sorte de « subselect » sur l'appareil (qui est un Descendant), cherchant tous les Interface éléments qu'il contient.

Il crée un nouveau DeviceInterface pour chaque "interface" sous chaque périphérique.

+0

Merci qui ressemble beaucoup plus agréable, je vais donner un coup de feu plus tard :) Ouais – user299342

+0

qui est sur place, cheers! – user299342

1

rapide et sale

var query = from device in document.Descendants("device") 
      select new 
      { 
       ID = device.Attribute("id").Value, 
       Name = device.Attribute("name").Value, 
       Interfaces = from deviceInterface in device.Descendants("interface") 
          select new 
          { 
           ID = deviceInterface.Attribute("id").Value, 
           Description = deviceInterface.Attribute("description") 
          } 
      }; 
+0

Vous avez encore besoin d'itérer sur 'query' pour créer (ou remplir) une' List '(voir' lsDevices' dans le code affiché). –