2010-03-22 11 views
5

Tengo un problema al hacer que funcione una consulta LINQ. Tengo este XML:Consulta anidada de Linq a 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> 

Y este código:

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

Mi objeto de dispositivo contiene una lista de DeviceInterfaces que necesito para llenar del XML. Por el momento, mi código solo rellena la primera interfaz, las siguientes se ignoran y no puedo entender por qué.

También agradecería cualquier comentario sobre si esta es o no la manera correcta de hacerlo. Los foreach anidados parecen un poco desordenado me

Saludos

Respuesta

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 
    } 

El punto básico aquí es que lo hace una especie de "subselección" en el dispositivo (que es un Descendant), buscando todos los Interface elementos que contiene

Crea un nuevo DeviceInterface para cada "interfaz" debajo de cada dispositivo.

+0

Gracias que parece mucho más agradable, voy a darle una oportunidad más adelante :) – user299342

+0

Sí que es perfecto, saludos! – user299342

1

rápida y sucia

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

Aún necesita iterar sobre 'query' para crear (o rellenar) una' List '(vea' lsDevices' en el código publicado). –