Udostępnij za pośrednictwem


Porównanie metody XPath i LINQ to XML

XPath i LINQ to XML są podobne w jakiś sposób. Oba te elementy mogą służyć do wykonywania zapytań względem drzewa XML, zwracania takich wyników jak kolekcja elementów, kolekcja atrybutów, kolekcja węzłów lub wartość elementu lub atrybutu. Istnieją jednak znaczące różnice między dwiema opcjami.

Różnice między językami XPath i LINQ to XML

Funkcja XPath nie zezwala na projekcję nowych typów. Może zwracać tylko kolekcje węzłów z drzewa, natomiast LINQ to XML może wykonywać zapytanie i projektować graf obiektu lub drzewo XML w nowym kształcie. Zapytania LINQ to XML mogą wykonywać znacznie więcej niż wyrażenia XPath.

Wyrażenia XPath istnieją w izolacji w ciągu. Kompilator języka C# nie może pomóc w analizowaniu wyrażenia XPath w czasie kompilacji. Natomiast zapytania LINQ to XML są analizowane i kompilowane przez kompilator języka C#. Kompilator może przechwytywać wiele błędów zapytań.

Wyniki XPath nie są silnie typizowane. W wielu okolicznościach wynik oceny wyrażenia XPath jest obiektem i zależy od dewelopera w celu określenia odpowiedniego typu i rzutowania wyniku w razie potrzeby. Natomiast projekcje z zapytania LINQ to XML są silnie typizowane.

Kolejność wyników

Zalecenie XPath 1.0 wskazuje, że kolekcja, która jest wynikiem oceny wyrażenia XPath, jest nieurządkowana.

Jednak w przypadku iteracji za pośrednictwem kolekcji zwracanej przez metodę osi XPath LINQ to XML węzły w kolekcji są zwracane w kolejności dokumentu. Jest to przypadek nawet w przypadku uzyskiwania dostępu do osi XPath, w których predykaty są wyrażane pod względem odwrotnej kolejności dokumentów, takich jak preceding i preceding-sibling.

Z kolei większość osi LINQ to XML zwraca kolekcje w kolejności dokumentów. Jednak dwa z nich Ancestors i AncestorsAndSelf, zwracają kolekcje w odwrotnej kolejności dokumentów. Poniższa tabela wylicza osie i wskazuje kolejność kolekcji dla każdej z nich:

Oś LINQ to XML Zamawianie
XContainer.DescendantNodes Kolejność dokumentów
XContainer.Descendants Kolejność dokumentów
XContainer.Elements Kolejność dokumentów
XContainer.Nodes Kolejność dokumentów
XContainer.NodesAfterSelf Kolejność dokumentów
XContainer.NodesBeforeSelf Kolejność dokumentów
XElement.AncestorsAndSelf Odwrotna kolejność dokumentów
XElement.Attributes Kolejność dokumentów
XElement.DescendantNodesAndSelf Kolejność dokumentów
XElement.DescendantsAndSelf Kolejność dokumentów
XNode.Ancestors Odwrotna kolejność dokumentów
XNode.ElementsAfterSelf Kolejność dokumentów
XNode.ElementsBeforeSelf Kolejność dokumentów
XNode.NodesAfterSelf Kolejność dokumentów
XNode.NodesBeforeSelf Kolejność dokumentów

Predykaty pozycyjne

W wyrażeniu XPath predykaty pozycyjne są wyrażane w kolejności dokumentu dla wielu osi, ale są wyrażane w odwrotnej kolejności dokumentu dla osi odwrotnych. Osie odwrotne to: preceding, , ancestorpreceding-siblingi ancestor-or-self. Na przykład wyrażenie preceding-sibling::*[1] XPath zwraca bezpośrednio poprzednie elementy równorzędne. Jest to przypadek, mimo że ostateczny zestaw wyników jest przedstawiony w kolejności dokumentu.

Z kolei wszystkie predykaty pozycyjne w LINQ to XML są zawsze wyrażane pod względem kolejności osi. Na przykład anElement.ElementsBeforeSelf().ElementAt(0) zwraca pierwszy element podrzędny elementu nadrzędnego elementu, którego dotyczy zapytanie, a nie bezpośredni element równorzędny. Inny przykład: anElement.Ancestors().ElementAt(0) zwraca element nadrzędny.

Jeśli chcesz znaleźć bezpośrednio poprzedni element w linQ to XML, napisz następujące wyrażenie:

ElementsBeforeSelf().Last()
ElementsBeforeSelf().Last()

Różnice wydajności

Zapytania XPath korzystające z funkcji XPath w linQ to XML będą wolniejsze niż zapytania LINQ to XML.

Porównanie kompozycji

Kompozycja zapytania LINQ to XML jest podobna do kompozycji wyrażenia XPath, ale składnia jest bardzo inna.

Jeśli na przykład masz element w zmiennej o nazwie , i chcesz znaleźć element wnuka o nazwie we wszystkich elementach podrzędnych o nazwie customersCompanyNameCustomer, należy napisać to wyrażenie XPath:

customers.XPathSelectElements("./Customer/CompanyName")
customers.XPathSelectElements("./Customer/CompanyName")

Równoważne zapytanie LINQ to XML:

customers.Elements("Customer").Elements("CompanyName")
customers.Elements("Customer").Elements("CompanyName")

Istnieją podobne równoległości dla każdej osi XPath.

Oś XPath Oś LINQ to XML
podrzędne (oś domyślna) XContainer.Elements
Element nadrzędny (..) XObject.Parent
oś atrybutu (@) XElement.Attribute

lub

XElement.Attributes
oś przodka XNode.Ancestors
oś ancestor-or-self XElement.AncestorsAndSelf
oś potomna (//) XContainer.Descendants

lub

XContainer.DescendantNodes
potomne lub samozwań XElement.DescendantsAndSelf

lub

XElement.DescendantNodesAndSelf
następujące elementy równorzędne XNode.ElementsAfterSelf

lub

XNode.NodesAfterSelf
poprzedni element równorzędny XNode.ElementsBeforeSelf

lub

XNode.NodesBeforeSelf
Następujące Brak bezpośredniego odpowiednika.
Poprzednim Brak bezpośredniego odpowiednika.