Gewusst wie: Schreiben einer Abfrage, die Elemente auf Grundlage des Kontexts sucht
Aktualisiert: November 2007
Es kann vorkommen, dass Sie eine Abfrage schreiben möchten, die Elemente auf der Grundlage ihres Kontexts sucht. Dabei soll die Filterung auf den vorausgehenden oder folgenden nebengeordneten Elementen erfolgen. Außerdem möchten Sie vielleicht auch nach untergeordneten oder indirekt übergeordneten Elementen filtern.
Um dies zu bewerkstelligen, können Sie eine Abfrage schreiben und die Ergebnisse dieser Abfrage in der where-Klausel verwenden. Wenn Sie zunächst eine Prüfung auf NULL-Werte vornehmen müssen und dann den Wert testen, empfiehlt es sich, die Abfrage in einer let-Klausel durchzuführen und die Ergebnisse dann in der where-Klausel zu verwenden.
Beispiel
Im folgenden Beispiel werden alle p-Elemente ausgewählt, die sofort von einem ul-Element gefolgt werden.
XElement doc = XElement.Parse(@"<Root>
<p id=""1""/>
<ul>abc</ul>
<Child>
<p id=""2""/>
<notul/>
<p id=""3""/>
<ul>def</ul>
<p id=""4""/>
</Child>
<Child>
<p id=""5""/>
<notul/>
<p id=""6""/>
<ul>abc</ul>
<p id=""7""/>
</Child>
</Root>");
IEnumerable<XElement> items =
from e in doc.Descendants("p")
let z = e.ElementsAfterSelf().FirstOrDefault()
where z != null && z.Name.LocalName == "ul"
select e;
foreach (XElement e in items)
Console.WriteLine("id = {0}", (string)e.Attribute("id"));
Dim doc As XElement = _
<Root>
<p id='1'/>
<ul>abc</ul>
<Child>
<p id='2'/>
<notul/>
<p id='3'/>
<ul>def</ul>
<p id='4'/>
</Child>
<Child>
<p id='5'/>
<notul/>
<p id='6'/>
<ul>abc</ul>
<p id='7'/>
</Child>
</Root>
Dim items As IEnumerable(Of XElement) = _
From e In doc...<p> _
Let z = e.ElementsAfterSelf().FirstOrDefault() _
Where z IsNot Nothing AndAlso z.Name.LocalName = "ul" _
Select e
For Each e As XElement In items
Console.WriteLine("id = {0}", e.@<id>)
Next
Dieser Code erzeugt die folgende Ausgabe:
id = 1
id = 3
id = 6
Im folgenden Beispiel wird dieselbe Abfrage für XML in einem Namespace gezeigt. Weitere Informationen dazu finden Sie unter Arbeiten mit XML-Namespaces.
XElement doc = XElement.Parse(@"<Root xmlns='http://www.adatum.com'>
<p id=""1""/>
<ul>abc</ul>
<Child>
<p id=""2""/>
<notul/>
<p id=""3""/>
<ul>def</ul>
<p id=""4""/>
</Child>
<Child>
<p id=""5""/>
<notul/>
<p id=""6""/>
<ul>abc</ul>
<p id=""7""/>
</Child>
</Root>");
XNamespace ad = "http://www.adatum.com";
IEnumerable<XElement> items =
from e in doc.Descendants(ad + "p")
let z = e.ElementsAfterSelf().FirstOrDefault()
where z != null && z.Name == ad.GetName("ul")
select e;
foreach (XElement e in items)
Console.WriteLine("id = {0}", (string)e.Attribute("id"));
Imports <xmlns='http://www.adatum.com'>
Module Module1
Sub Main()
Dim doc As XElement = _
<Root>
<p id='1'/>
<ul>abc</ul>
<Child>
<p id='2'/>
<notul/>
<p id='3'/>
<ul>def</ul>
<p id='4'/>
</Child>
<Child>
<p id='5'/>
<notul/>
<p id='6'/>
<ul>abc</ul>
<p id='7'/>
</Child>
</Root>
Dim items As IEnumerable(Of XElement) = _
From e In doc...<p> _
Let z = e.ElementsAfterSelf().FirstOrDefault() _
Where z IsNot Nothing AndAlso z.Name = GetXmlNamespace().GetName("ul") _
Select e
For Each e As XElement In items
Console.WriteLine("id = {0}", e.@<id>)
Next
End Sub
End Module
Dieser Code erzeugt die folgende Ausgabe:
id = 1
id = 3
id = 6
Siehe auch
Konzepte
Einfache Abfragen (LINQ to XML)