2009-02-23 10 views
11

Ich habe folgende Datei:Abfrage xmlnode mit 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> 

Ich möchte Informationen, um herauszufinden, wie: Gesamt Artikel in Günstige und Costly, Liste aller Kategorien (wie Kochen, Garten, Dekoration ...) , Liste der sortierten Kategorie und wählen Sie nur das Produkt aus, das 'teuer' ist

Wie kann ich mit LINQ tun? Ich tat dies bis jetzt:

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

Antwort

9

Ihre XML-Struktur ist bedauerlich, da es ein Produktelement für drei Ebenen der Hierarchie verwendet. Haben Sie ähnliche Elemente wie "Haushalt"?

Angenommen, wir nur die Haushalts diejenigen wollen, können Sie verwenden:

Graf Artikel in jeder billig/teuer

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

Liste alle Kategorien

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

zu Sortiere das, benutze einfach .OrderBy(x => x) am Ende.

'teuer' Produkte auswählen

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

Ich brauche zu lehren mich LINQ wirklich ... klingt soooo einfach so:) – balexandre

+0

Ich habe die XML geändert und es funktioniert .. Danke für die Antwort –

+1

Ich bezweifle Jon wollte Sie einzelne Elemente * innerhalb * der Daten umbenennen; eher, um verschiedene Namen auf jedem * Level * ... –

9

Nun, ich persönlich finde es einfacher, mit 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")); 
    }