2011-01-13 6 views
1

Hallo, ich versuche, eine einfache Linq-Abfrage aus einem Tutorial zu schreiben Ich lese. Aber ich kann es nicht zur Arbeit bringen. Ich versuche, die Adresse im angehängten xml-Dokument anzuzeigen, kann aber nur die erste anzeigen. Kann mir jemand helfen, herauszufinden, warum beide nicht gedruckt werden? Vielen Danklinq to xml Enumeration über Nachkommen

<?xml version="1.0" encoding="utf-8" ?> 
<Emails> 
    <Email group="FooBar"> 
    <Subject>Test subject</Subject> 
    <Content>Test Content</Content> 
    <EmailTo> 
     <Address>[email protected]</Address> 
     <Address>[email protected]</Address> 
    </EmailTo> 
    </Email> 
</Emails> 




    Dim steve = (From email In emailList.Descendants("Email") _ 
       Where (email.Attribute("group").Value.Equals("FooBar")) _ 
       Select content = email.Element("EmailTo").Descendants("Address")).ToList() 



    If Not steve Is Nothing Then 
     For Each addr In steve 
      Console.WriteLine(addr.Value) 
     Next 
     Console.ReadLine() 
    End If 

Antwort

2

Ihre aktuelle Abfrage gibt eine List<IEnumerable<XElement>> zurück. Das bedeutet, dass Sie zwei verschachtelte foreach-Schleifen benötigen: eine Schleife über die Liste und eine weitere Schleife über den Inhalt der IEnumerable<XElement>-Schleife.

Stattdessen können Sie Ihre LINQ-Abfrage aktualisieren, um die Enumerable.SelectMany-Methode zu verwenden und direkt zu den Adressen zu gelangen. Im Abfrageformat wird eine dargestellt, indem eine zweite from-Klausel verwendet wird, um eine Unterabfrage anzuzeigen. Dies würde wie folgt aussehen:

Dim query = (From email In emailList.Descendants("Email") _ 
      Where (email.Attribute("group").Value.Equals("FooBar")) _ 
      From addr In email.Element("EmailTo").Descendants("Address") _ 
      Select addr.Value).ToList() 

If query.Any() Then 
    For Each addr In query 
     Console.WriteLine(addr) 
    Next 
End If 

Auch ist die ToList nicht erforderlich, wenn Sie nur über die Ergebnisse wiederholen wollen und beabsichtigen nicht für andere Zwecke das Ergebnis als Liste zu verwenden.

EDIT: erklären, wie diese Abfrage Werke lassen Sie es brechen in zwei Teile nach unten:

Erstens:

From email In emailList.Descendants("Email") _ 
Where (email.Attribute("group").Value.Equals("FooBar")) _ 

Diese Anfragen für alle <Email> Knoten und passt nur diejenigen, die eine haben Gruppe Attributwert von "FooBar".

Zweitens:

From addr In email.Element("EmailTo").Descendants("Address") _ 
Select addr.Value 

Dies ist eine Unterabfrage, die der erste Teil (oben) beendet weiter, wo. Es ist im Wesentlichen eine Möglichkeit, die Ergebnisse der ursprünglichen Abfrage weiter abzufragen. Hier suchen wir nach allen <Address> Knoten und wählen schließlich deren Value für den inneren Text der Knoten aus. Der Grund dafür ist, dass Descendants("Address") einen IEnumerable<XElement> zurückgibt, der alle "Address" -Elemente enthält. Wir müssen eine zusätzliche Abfrage durchführen (oder foreach), um über diese Werte zu iterieren und ihre Werte zu extrahieren.

Ein anderer Weg, dies zu veranschaulichen, ist es durch Brechen in zwei Abfragen nach unten:

Dim query1 = From email In emailList.Descendants("Email") _ 
      Where (email.Attribute("group").Value.Equals("FooBar")) 
      Select email.Element("EmailTo").Descendants("Address") 
Dim query2 = query1.SelectMany(Function(addr) addr.Select(Function(a) a.Value)) 

die Verwendung Hinweis SelectMany in query2. Die Select in query2 ist dieser zusätzliche Aufwand, um über die IEnumerable Schleife, die ich bereits erwähnt habe. Die ursprüngliche Abfrage ist klarer als query1/query2, aber ich habe sie nur geschrieben, um den Punkt zu verdeutlichen.

+0

Ich verstehe nicht vollständig, wie Ihre Linq-Anweisung funktioniert. Kannst du es für mich aufschlüsseln oder auf einige Ressourcen zeigen, die ich lesen kann? Was ich nicht verstehe, ist die zweite Klausel. Wie gibt mir das, was ich brauche? Danke für die Antwort und helfen – gh9

+0

Sorry, nur auf die Ergebnisse zurück geschaut und die Ergebnisse ich erwarte sind [email protected] NEWLINE [email protected] was ich bin immer ist [email protected] NEWLINE [email protected] – gh9

+0

hoppla, mein Fehler, ich habe deine Select-Anweisung nicht entschuldigt. Antwort funktioniert wie angekündigt, können Sie mir erklären, warum es funktioniert.Danke – gh9