Sdílet prostřednictvím


Porovnání jazyka XPath a technologie LINQ to XML

XPath a LINQ to XML jsou podobné některým způsobem. Obojí lze použít k dotazování stromu XML, který vrací například výsledky jako kolekci prvků, kolekci atributů, kolekci uzlů nebo hodnotu elementu nebo atributu. Mezi těmito dvěma možnostmi však existují významné rozdíly.

Rozdíly mezi XPath a LINQ to XML

XPath neumožňuje projekci nových typů. Může vracet pouze kolekce uzlů ze stromu, zatímco LINQ to XML může spustit dotaz a projektovat objektový graf nebo strom XML v novém obrazci. Dotazy LINQ to XML mohou provádět mnohem více než výrazy XPath.

Výrazy XPath existují izolovaně v řetězci. Kompilátor jazyka C# nemůže pomoct analyzovat výraz XPath v době kompilace. Naproti tomu dotazy LINQ to XML se parsují a kompilují kompilátorem jazyka C#. Kompilátor může zachytit mnoho chyb dotazu.

Výsledky XPath nejsou silného typu. V řadě okolností je výsledkem vyhodnocení výrazu XPath objekt a je na vývojáři, aby určil správný typ a v případě potřeby výsledek přetypuje. Naproti tomu projekce z dotazu LINQ to XML jsou silně napsané.

Řazení výsledků

Doporučení XPath 1.0 uvádí, že kolekce, která je výsledkem vyhodnocení výrazu XPath, není seřazená.

Při iteraci kolekcí vrácenou metodou osy XPath LINQ to XML se však uzly v kolekci vrátí v pořadí dokumentu. To je případ i při přístupu k osám XPath, kde jsou predikáty vyjádřeny z hlediska pořadí obráceného dokumentu, například preceding a preceding-sibling.

Naproti tomu většina os LINQ to XML vrací kolekce v pořadí dokumentů. Dva z nich Ancestors ale vrátí AncestorsAndSelfkolekce v obráceném pořadí dokumentů. Následující tabulka uvádí osy a označuje pořadí kolekcí pro každou z nich:

Osa LINQ to XML Řazení
XContainer.DescendantNodes Pořadí dokumentů
XContainer.Descendants Pořadí dokumentů
XContainer.Elements Pořadí dokumentů
XContainer.Nodes Pořadí dokumentů
XContainer.NodesAfterSelf Pořadí dokumentů
XContainer.NodesBeforeSelf Pořadí dokumentů
XElement.AncestorsAndSelf Obrácené pořadí dokumentů
XElement.Attributes Pořadí dokumentů
XElement.DescendantNodesAndSelf Pořadí dokumentů
XElement.DescendantsAndSelf Pořadí dokumentů
XNode.Předky Obrácené pořadí dokumentů
XNode.ElementsAfterSelf Pořadí dokumentů
XNode.ElementsBeforeSelf Pořadí dokumentů
XNode.NodesAfterSelf Pořadí dokumentů
XNode.NodesBeforeSelf Pořadí dokumentů

Poziční predikáty

Ve výrazu XPath jsou poziční predikáty vyjádřeny z hlediska pořadí dokumentů pro mnoho os, ale jsou vyjádřeny v obráceném pořadí dokumentu pro obrácené osy. Obrácené osy jsou: preceding, preceding-sibling, ancestora ancestor-or-self. Například výraz preceding-sibling::*[1] XPath vrátí bezprostředně předcházející stejné stejné hodnoty. To je případ, i když se konečná sada výsledků zobrazí v pořadí dokumentu.

Naproti tomu všechny poziční predikáty v JAZYCE LINQ to XML jsou vždy vyjádřeny z hlediska pořadí osy. Například anElement.ElementsBeforeSelf().ElementAt(0) vrátí první podřízený prvek nadřazeného prvku dotazovaného prvku, nikoli bezprostředně předcházející stejné úrovně. Další příklad: anElement.Ancestors().ElementAt(0) vrátí nadřazený prvek.

Pokud byste chtěli najít bezprostředně předcházející prvek v JAZYCE LINQ to XML, napsali byste následující výraz:

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

Rozdíly v výkonu

Dotazy XPath, které používají funkce XPath v LINQ to XML, budou pomalejší než dotazy LINQ to XML.

Porovnání složení

Složení dotazu LINQ to XML je podobné složení výrazu XPath, ale syntaxe je velmi odlišná.

Pokud například máte prvek v proměnné s názvem customersa chcete najít vnoučácký prvek pojmenovaný CompanyName pod všemi podřízenými elementy s názvem Customer, napíšete tento výraz XPath:

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

Ekvivalentní dotaz LINQ to XML je:

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

Existují podobné paralely pro každou osu XPath.

Osa XPath Osa LINQ to XML
podřízený (výchozí osa) XContainer.Elements
Nadřazený objekt (..) XObject.Parent
Osa atributu (@) XElement.Attribute

nebo

XElement.Attributes
osa předků XNode.Ancestors
Osa nadřazeného nebo vlastního původu XElement.AncestorsAndSelf
osa potomků (//) XContainer.Descendants

nebo

XContainer.DescendantNodes
potomků nebo samoobsluhod XElement.DescendantsAndSelf

nebo

XElement.DescendantNodesAndSelf
sledování na stejné XNode.ElementsAfterSelf

nebo

XNode.NodesAfterSelf
předchozí nástavbový XNode.ElementsBeforeSelf

nebo

XNode.NodesBeforeSelf
Následující Žádný přímý ekvivalent.
Předchozí Žádný přímý ekvivalent.