2009-07-14 12 views
1

wurde mein Gehirn bestechen versucht, herauszufinden, wie eine linq XML-Abfrage durchzuführen."wo" Abfrage mit linq xml

i die Abfrage möchte eine Liste aller „Produkt“ Einzelteile zurückbringen, wo die Kategorie/name = „Erste Kategorie“ in der folgenden XML-

<catalog> 
    <category> 
    <name>First Category</name> 
    <order>0</order> 
    <product> 
     <name>First Product</name> 
     <order>0</order> 
    </product> 
    <product> 
     <name>3 Product</name> 
     <order>2</order> 
    </product> 
    <product> 
     <name>2 Product</name> 
     <order>1</order> 
    </product> 
    </category> 
</catalog> 

Antwort

6

Wie so:

XDocument doc = XDocument.Parse(xml); 
    var qry = from cat in doc.Root.Elements("category") 
       where (string)cat.Element("name") == "First Category" 
       from prod in cat.Elements("product") 
       select prod; 

oder vielleicht mit einem anonymen Typ zu:

XDocument doc = XDocument.Parse(xml); 
    var qry = from cat in doc.Root.Elements("category") 
       where (string)cat.Element("name") == "First Category" 
       from prod in cat.Elements("product") 
       select new 
       { 
        Name = (string)prod.Element("name"), 
        Order = (int)prod.Element("order") 
       }; 
    foreach (var prod in qry) 
    { 
     Console.WriteLine("{0}: {1}", prod.Order, prod.Name); 
    } 
+0

Es scheint nur eine 'Kategorie' mit dem Namen * Erste Kategorie * zu geben, also ist' Single' wahrscheinlich hier besser geeignet. – Noldorin

+1

Ich denke, es ist sicher anzunehmen, dass dies ein Fragment aus einem größeren xml-Block ist, ansonsten ist die Filterung redundant. In diesem Fall können Sie nicht sagen, wie viele Kategorien mit Vornamen existieren ... –

+1

Möglicherweise, obwohl * name * typischerweise Eindeutigkeit impliziert. – Noldorin

0

Sie wollen die Single Erweiterung Methode verwenden, Hier. Versuchen Sie Folgendes:

var category = doc.RootNode.Elements("category").Single(
    c => c.Attribute("name").Value == "First Category"); 
var products = category.Elements("product"); 

Beachten Sie, dass dies voraus, dass Sie nur eine Kategorie mit dem Namen „Erste Kategorie“ haben. Wenn Sie möglicherweise mehr haben, empfehle ich Marc Lösung zu verwenden; Andernfalls sollte dies die geeignetere/effizientere Lösung sein. Außerdem wird eine Ausnahme ausgelöst, wenn der Knoten category keinen untergeordneten Knoten name hat. Ansonsten sollte es genau das tun, was Sie wollen.

+0

Grund für die nach unten Abstimmung bitte? – Noldorin

+0

Jetzt verwirrt mich das. Diese Antwort ist völlig korrekt, vorausgesetzt die (IMO gerechte) Annahme, dass das OP nur nach einer Kategorie mit der Bezeichnung "Erste Kategorie" sucht ... – Noldorin

+0

Ich stimme zu, dass es funktionieren sollte (obwohl das Attribut-Zeug einfacher sein könnte und Sie das Risiko eingehen) Auslösen von Ausnahmen, wenn eines der Elemente/Attribute fehlt); +1 hier ... Ich weiß nicht warum, aber alle originalen Antworten auf diese Frage wurden abgelehnt. –

1

Hier ist ein Beispiel:

 string xml = @"your XML"; 

     XDocument doc = XDocument.Parse(xml); 

     var products = from category in doc.Element("catalog").Elements("category") 
         where category.Element("name").Value == "First Category" 
         from product in category.Elements("product") 
         select new 
         { 
          Name = product.Element("name").Value, 
          Order = product.Element("order").Value 
         }; 
     foreach (var item in products) 
     { 
      Console.WriteLine("Name: {0} Order: {1}", item.Name, item.Order); 
     }