LINQ to XML, cz. 3 - Zapytania - kontynuacja

W poprzednim artykule został przedstawiony sposób dostępu do węzłów w dokumencie Xml za pomocą Linq To Xml. Jedną z bardziej interesujących rzeczy było to, że w Linq to Xml nie używa się wyrażeń XPath. Zamiast tego używa się metod, które bardzo przypominają pojedyncze kroki w wyrażeniach XPath. O ile w przypadku języka XPath kroki rozdzielone są znakiem '/' to w Linq To Xml wywołujemy poszczególne metody na wyniku zwróconym przez wywołanie metody funkcji (np. xDoc.Root.Elements("segment").Elements("wylot")). Oczywiście wybieranie węzłów z dokumentu Xmlowego to już cos ale w praktyce zazwyczaj zamiast wybierać z dokumentu wszystkie węzły o danej nazwie wybieramy tylko te które spełniają określone warunki. Przykładowo z następującego dokumentu (jest to ten sam dokument który był używany w poprzednich częściach cyklu):

<?xml version="1.0"?>
<wycieczka>
  <segment>
    <wylot kod-lotniska="SEA" data="2008-10-09T15:25Z">
Seattle-Tacoma International</wylot>
    <przylot kod-lotniska="LHR" data="2008-10-10T02:20Z">
London Heathrow</przylot>
  </segment>
  <segment>
    <wylot kod-lotniska="LHR" data="2008-10-10T05:35Z">
London Heathrow</wylot>
    <przylot kod-lotniska="WRO" data="2008-10-10T10:05Z">
Wroclaw Strachowice</przylot>
  </segment>
</wycieczka>

wybierzmy wszystkie elementy będące dziećmi elementu <segment>, których atrybut @kod-lotniska ma wartość "LHR". Zapytanie będzie wyglądać tak:

var elements = 
from el in xDoc.Elements("wycieczka").Elements("segment").Elements()
where (string)el.Attribute("kod-lotniska") == "LHR"
select el;

Jak to działa? Pierwsza linia jest swoistego rodzaju iteratorem. Zmienna el będzie przyjmowała kolejne wartości ze zbioru węzłów wybieranych przez wyrażenie:

xDoc.Elements("wycieczka").Elements("segment").Elements() 

(które swoją drogą powinno wyglądać znajomo z poprzedniego artykułu). W drugiej linii nakładamy warunek na zmienną el. W naszym przypadku jesteśmy zainteresowani tylko elementami których atrybut @kod-lotniska ma wartość "LHR". W ostatniej linii dodajemy do wynikowej kolekcji (var w przypadku zypytań Linqowych jest obiektem implementującym interfejs IEnumerable) el jeśli spełnia on warunek z linii drugiej ("select" w tym przypadku działa podobnie jak znane z języka C# "yield").