Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
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ą jako oddzielne elementy w ramach 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 wyników 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 iterując przez kolekcję zwracaną przez metodę osi XPath LINQ to XML, węzły są zwracane w kolejności ich występowania w dokumencie. 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 względem dokumentu. Poniższa tabela wylicza osie i wskazuje kolejność kolekcji dla każdej z nich:
Oś LINQ do XML | Zamówienie |
---|---|
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.PrzodkowieIOsobie | 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
, preceding-sibling
, ancestor
, i ancestor-or-self
. Na przykład wyrażenie XPath preceding-sibling::*[1]
zwraca bezpośrednio poprzedni element równorzędny. To nadal prawda, mimo że ostateczny zbiór wyników jest przedstawiony według kolejności dokumentów.
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 nadrzędnego elementu sprawdzanego, a nie bezpośredni poprzedzający 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.
Na przykład, jeśli masz element w zmiennej o nazwie customers
i chcesz znaleźć element wnuka o nazwie CompanyName
we wszystkich elementach podrzędnych o nazwie Customer
, powinieneś napisać takie 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 do XML |
---|---|
dziecko (oś domyślna) | XContainer.Elements |
Rodzic (..) | XObject.Parent |
oś atrybutu (@) | XElement.Attribute lub XElement.Attributes |
oś przodka | XNode.Ancestors |
oś przodka lub siebie | XElement.AncestorsAndSelf |
oś potomna (//) | XContainer.Descendants lub XContainer.DescendantNodes |
potomek lub ty sam | XElement.DescendantsAndSelf lub XElement.DescendantNodesAndSelf |
następujący element równorzędny | XNode.ElementsAfterSelf lub XNode.NodesAfterSelf |
poprzedni element rodzeństwa | XNode.ElementsBeforeSelf lub XNode.NodesBeforeSelf |
następujący | Brak bezpośredniego odpowiednika. |
poprzedzający | Brak bezpośredniego odpowiednika. |