2009-02-23 12 views
11

he archivo siguientes:xmlnode consulta utilizando LINQ

<root> 
    <Product desc="Household"> 
    <Product1 desc="Cheap"> 
     <Producta desc="Cheap Item 1" category="Cooking" /> 
     <Productb desc="Cheap Item 2" category="Gardening" /> 
    </Product1> 
    <Product2 desc="Costly"> 
     <Producta desc="Costly Item 1" category="Decoration"/> 
     <Productb desc="Costly Item 2" category="Furnishing" /> 
     <Productc desc="Costly Item 3" category="Pool" /> 
    </Product2> 
    </Product> 
</root> 

Quiero averiguar información como: artículos totales en barato y costoso, lista de todas las categorías (como cocinar, jardinería, decoración ...) , lista ordenada de categoría y seleccione sólo el producto que es 'costoso'

Cómo puedo hacer uso de LINQ. lo hice hasta ahora:

XElement xe = XElement.Load(Server.MapPath("~/product.xml")); 
???? 

Respuesta

9

Su estructura XML es lamentable, ya que utiliza un elemento de producto para tres niveles de la jerarquía. ¿Tiene otros elementos similares al "hogar"?

Suponiendo que sólo queremos los de uso doméstico, puede utilizar:

artículos cuentan en cada uno de barato/costosa

xe.Element("Product") // Select the Product desc="household" element 
    .Elements() // Select the elements below it 
    .Select(element => new { Name=(string) element.Attribute("desc"), 
          Count=element.Elements().Count() }); 

Lista de todas las categorías

xe.Descendants() // Select all descendant elements 
    .Attributes() // All attributes from all elements 
    // Limit it to "category" elements 
    .Where(attr => attr.Name == "category") 
    // Select the value 
    .Select(attr => attr.Value) 
    // Remove duplicates 
    .Distinct(); 

Para ordene esto, solo use .OrderBy(x => x) al final.

productos 'costosos'

Seleccione

xe.Descendants() // Select all elements 
    // Only consider those with a "Costly" description 
    .Where(element => (string) element.Attribute("desc") == "Costly") 
    // Select the subelements of that element, and flatten the result 
    .SelectMany(element => element.Elements()); 
+1

que realmente necesitan para enseñar a mí mismo LINQ ... suena taaaan fácil de esta manera:) – balexandre

+0

He cambiado el xml y está funcionando. Gracias por la respuesta –

+1

. Dudo que Jon haya pensado en cambiar el nombre de elementos individuales * dentro de * los datos; más bien para tener diferentes nombres en cada * nivel * ... –

9

Bueno, personalmente, me resulta más fácil con XmlDocument:

XmlDocument root = new XmlDocument(); 
    root.LoadXml(xml); // or .Load(path); 

    var categories = root.SelectNodes(
     "/root/Product/Product/Product/@category") 
     .Cast<XmlNode>().Select(cat => cat.InnerText).Distinct(); 
    var sortedCategories = categories.OrderBy(cat => cat); 
    foreach (var category in sortedCategories) 
    { 
     Console.WriteLine(category); 
    } 

    var totalItems = root.SelectNodes(
     "/root/Products/Product/Product").Count; 
    Console.WriteLine(totalItems); 

    foreach (XmlElement prod in root.SelectNodes(
     "/root/Product/Product[@desc='Costly']/Product")) 
    { 
     Console.WriteLine(prod.GetAttribute("desc")); 
    }