• Zwiększ rozmiar czcionki
  • Domyślny  rozmiar czcionki
  • Zmniejsz rozmiar czcionki
Home Artykuły .NET LINQ to XML, cz. 2 - Wstęp do zapytań

LINQ to XML, cz. 2 - Wstęp do zapytań

Email Drukuj PDF
Ocena użytkowników: / 2
SłabyŚwietny 

Pierwszy artykuł z serii zawierał wprowadzenie do technologii Linq to Xml oraz pokazywał w jaki sposób tworzyć lub ładować dokumenty Xmlowe. Oczywiście samo załadowanie dokumentu do pamięci to dopiero wstęp do prawdziwej zabawy.

Ponieważ jedną z najczęściej wykonywanych operacji jest wybieranie z dokumentu węzłów i/lub atrybutów zobaczmy jak to się robi w Linq to Xml (w przykładach użyjemy dokument z pierwszego artykułu cyklu który wygląda tak:

<?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>

).

Na początku coś bardzo prostego. Wybierzmy element root z wejściowego dokumentu.

XDocument xDoc = XDocument.Parse(xmlString);
XElement root = xDoc.Root;

To rzeczywiście nie było zbyt skomplikowane. Sprobujmy więc cos bardziej zaawansowanego - wybierzmy z dokumentu wszystkie elementy <wylot>. Zapytanie może wyglądać tak:

var wyloty = xDoc.Root.Elements("segment").Elements("wylot");

Ale może też wyglądać tak:

var wyloty = xDoc.Descendants("wylot");

Żeby wypisać wynik na ekranie można posłużyć się następującą pętlą:

foreach(var wylot in wyloty) {
Console.WriteLine(wylot);
}

Nawet pobieżna analiza powyższych zapytań prowadzi do takich przemyśleń:

  • wygląda na to, że w Linq To Xml nie używa się wyrażeń XPath
  • wprowadzone zostało jakieś tajemnicze słówko "var"

Q: Czy w Linq to Xml nie używa się wyrażeń XPath?
A: I tak i nie. W zapytaniach zalecane jest stosowanie metod odpowiadających mniej lub bardziej osiom (axes) w wyrażeniach XPath. To - wraz z klauzulą where (jeszcze nie wprowadzoną) oraz wyrażeniami lambda (o tym w późniejszych odcinkach cyklu) w zasadzie umożliwia wybieranie węzłów z dokumentów Xmlowych bez konieczności używania wyrażeń XPath. Miłośnicy (wielbiciele?) XPath mogą używać wyrażeń XPath podczas pracy z Linq To Xml (zaimplementowanych jako metody rozszerzające (ang. extension methods) w przestrzeni nazw System.Xml.XPath) jednak okupione to jest sporą stratą wydajności zapytań.

Q: Co to jest "var"?
A: var jest wprowadzonym w C# 3.0 słowem kluczowym, które mówi kompilatorowi, żeby sam określił/wywnioskował typ zmiennej (ang. implicit type). Najłatwiej zrozumieć to na przykładzie (z msdn'a swoją drogą):

var i = 10; // implicitly typed
int i = 10; // explicitly typed

W obu przypadkach typ zmiennej i jest taki sam - int. Różnica jest taka, że w pierwszym przypadku to kompilator określa (wnioskuje) typ zmiennej podczas gdy w drugim przypadku jest to programista.
Jest jeszcze jeden przypadek, w którym stosuje się słowo kluczowe "var" (tak naprawde jest to wtedy obowiązkowe) - mianowicie klasy anonimowe (ang. anonymous classes). Klasy anonimowe są często stosowane wraz zapytaniami Linqowymi więc temat ten na pewno będzie jeszcze poruszony w dalszych odcinkach cyklu.
Dygresja: Moja osobista opinia na temat słowa "var" jest taka, że w zasadzie powinno się go unikać. Jednym z wyjątków jest Linq - praca z klasami anonimowymi wymusza używanie "var", a stosowanie np. IEnumerable<XElement> zamiast "var" (taki jest typ zmiennej wyloty z przykładowych zapytań), aż tyle nie wnosi.

Artykuł umieszczono dzięki uprzejmości xml.com.pl.

Poprawiony: środa, 15 lipca 2009 20:30  
Komentarze (4)
1 środa, 15 lipca 2009 22:00
szomiz
Nie podoba mi się ta hybryda DOM,a i xPath'a :(

Wnosi coś znacząco nowego, dodaje coś czego w "standardowych" specyfikacjach nie da się zrealizować?

Moim zdaniem - takie trochę dłubanie w strukturze dla ubogich :/
2 piątek, 30 października 2009 08:38
Jak się popatrzy na takie np. LINQ to XML to niby nic takiego - tak mi się też na początku wydawało. Ale jak się zacząłem tym bawić w konkretnych aplikacjach .NET-owych, to muszę powiedzieć, że całkiem przyjemne narzędzie.

Niby wszystko można załatwić czymś innym i to standardowym np. XPath-em, ale użycie LINQ będzie bardzo wygodne i przejrzyste, a co najważniejsze i to uważam za największą zaletę: już na etapie kompilacji sprawdzone zostaną typy wszystkich danych.

Tak więc moim zdaniem LINQ to XML ma się do XPath, jak LINQ to SQL do czystego SQL'a.
3 wtorek, 05 stycznia 2010 08:13
Paweł Kadłuczka
Tez mi sie kiedys wydawalo ze Linq to Xml nie wnosi nic nowego. Ale prawda jest taka, ze przynajmniej dla mnie Linq jest o wiele mniej rozwlekly niz DOM i XPath i do tego o wiele wygodniejszy - wystarczy sprobowac zbudowac dokument "programistycznie". Moim zdaniem Linq to Xml zatyka tez dziure gdzie transformacja to troche "za duzo" (ladowanie, kompilacja i sama transformacja) a DOM to troche "zbyt uciazliwe". Mozliwosc robienia joinow na dokumentach Xmlowych (doslownie jedna linijka), wrecz naturalna wspolpraca z Linq to Objects oraz mozliwosc dodawania anotacji do węzłów to są "killer features".
Nie zgadzam sie ze na etapie kompilacji zostana sprawdzone wszystkie typy danych (to chyba byl cel Linq to XSD) - nie wiesz jaki dostaniesz dokument xmlowy wiec rzutowanie (za pomoca jawnego operatora konwersji) do int-a moze sie skonczyc wyjatkiem. Zakladajac ze wszystko co wyczytasz uda sie odpowiednio zrzutowac rzeczywiscie praca staje sie latwiejsza.
Nie zgadzam sie ze Linq to Xml ma sie do XPath jak Linq to SQL do SQL - Linq to SQL wymaga dodatkowych "dekoracji" na klasach encji (czy jak sie to tam nazywa) zeby odzwierciedlic strukture zrodla danych - w Linq to Xml nie ma nic takiego. Zapytania Linq to Sql sa ostatecznie tlumaczone na odpowiadajace im zapytania SQLowe podczas zapytania Linq to Xml *nie sa* tlumaczone na odpowiedajace im zapytania XPathowe.
Niemniej jednak tzw. "bridge classes" umozliwiaja wykonywanie zapytan XPathowych, transformacji XSLT czy walidacji za pomoca XSD na obiektach XDocument. Wiec mozna polaczyc Linq to Xml z XPath. Ma to sens w szczegolnosci gdy chce sie budowac zapytania dynamicznie - wciaz latwiej jest zlozyc XPath niz grzebac sie w Expression Trees, lambdach itp.

moozzyk / Paweł Kadłuczka

P.S. A może po prostu jestem skrzywiony...
4 sobota, 09 stycznia 2010 11:32
To prawda, że w miarę używania, Linq staje się nardzo naturalny i co moim zdaniem najlepsze, uzupełnia się z pozostałymi Linq'ami.

Dodaj swój komentarz

Imię:
Adres e-mail:
Strona WWW:
Treść (możesz używać HTML):
JoomlaWatch Stats 1.2.9 by Matej Koval

Użytkownicy

Naszą witrynę przegląda teraz 1 gość