Vergleich zwischen XPath und LINQ to XMLComparison of XPath and LINQ to XML

XPath und LINQ to XML haben hinsichtlich ihrer Funktionalität einige Gemeinsamkeiten.XPath and LINQ to XML offer some similar functionality. Beide können verwendet werden, um Elementauflistungen, Attributauflistungen, Knotenauflistungen oder die Werte von Elementen oder Attributen aus XML-Strukturen abzurufen.Both can be used to query an XML tree, returning such results as a collection of elements, a collection of attributes, a collection of nodes, or the value of an element or attribute. Aber es gibt auch einige Unterschiede.However, there are also some differences.

Unterschiede zwischen XPath und LINQ to XMLDifferences Between XPath and LINQ to XML

XPath lässt keine Projektion neuer Typen zuXPath does not allow projection of new types. Es können nur Auflistungen der Knoten aus der Struktur zurückgegeben werden. LINQ to XML kann dagegen eine Abfrage ausführen und ein Objektdiagramm oder eine XML-Struktur in einer neuen Form projizieren.It can only return collections of nodes from the tree, whereas LINQ to XML can execute a query and project an object graph or an XML tree in a new shape. LINQ to XML-Abfragen umfassen deutlich mehr Funktionen und sind viel leistungsstärker als XPath-Ausdrücke. queries encompass much more functionality and are much more powerful than XPath expressions.

XPath-Ausdrücke existieren innerhalb einer Zeichenfolge isoliert.XPath expressions exist in isolation within a string. Der C#-Compiler kann nicht helfen, den XPath-Ausdruck beim Kompilieren zu analysieren.The C# compiler cannot help parse the XPath expression at compile time. LINQ to XML-Abfragen werden dagegen vom C#-Compiler analysiert und kompiliert.By contrast, LINQ to XML queries are parsed and compiled by the C# compiler. Der Compiler kann eine Vielzahl von Abfragefehlern abfangen.The compiler is able to catch many query errors.

XPath-Ergebnisse sind nicht stark typisiert.XPath results are not strongly typed. In vielen Situationen ist das Ergebnis der Auswertung eines XPath-Ausdrucks ein Objekt, und es obliegt dem Entwickler, den richtigen Typ zu bestimmen und das Ergebnis nach Bedarf zu konvertieren.In a number of circumstances, the result of evaluating an XPath expression is an object, and it is up to the developer to determine the proper type and cast the result as necessary. Im Gegensatz dazu sind die Projektionen aus einer LINQ to XML-Abfrage stark typisiert.By contrast, the projections from a LINQ to XML query are strongly typed.

Reihenfolge der ErgebnisanzeigeResult Ordering

Laut XPath 1.0-Empfehlung ist eine Auflistung, die das Ergebnis der Auswertung eines XPath-Ausdrucks ist, nicht geordnet.The XPath 1.0 Recommendation states that a collection that is the result of evaluating an XPath expression is unordered.

Beim Durchlaufen einer Auflistung, die von einer LINQ to XML-XPath-Achsenmethode zurückgegeben wurde, werden die Knoten in der Auflistung jedoch in der Dokumentreihenfolge zurückgegeben.However, when iterating through a collection returned by a LINQ to XML XPath axis method, the nodes in the collection are returned in document order. Dies ist auch beim Zugriff auf die XPath-Achsen der Fall, wo beim Ausdrücken von Prädikaten auf die umgekehrte Dokumentreihenfolge zurückgegriffen wird, wie z. B. preceding und preceding-sibling.This is the case even when accessing the XPath axes where predicates are expressed in terms of reverse document order, such as preceding and preceding-sibling.

Die meisten LINQ to XML-Achsen geben Auflistungen in der Dokumentreihenfolge zurück, aber bei zweien, Ancestors und AncestorsAndSelf, werden die Auflistungen in umgekehrter Dokumentreihenfolge zurückgegeben.By contrast, most of the LINQ to XML axes return collections in document order, but two of them, Ancestors and AncestorsAndSelf, return collections in reverse document order. In der folgenden Tabelle werden die Achsen aufgeführt, und es wird jeweils die Auflistungsreihenfolge angegeben:The following table enumerates the axes, and indicates collection order for each:

LINQ to XML-AchseLINQ to XML axis SortierenOrdering
XContainer.DescendantNodesXContainer.DescendantNodes DokumentreihenfolgeDocument order
XContainer.DescendantsXContainer.Descendants DokumentreihenfolgeDocument order
XContainer.ElementsXContainer.Elements DokumentreihenfolgeDocument order
XContainer.NodesXContainer.Nodes DokumentreihenfolgeDocument order
XContainer.NodesAfterSelfXContainer.NodesAfterSelf DokumentreihenfolgeDocument order
XContainer.NodesBeforeSelfXContainer.NodesBeforeSelf DokumentreihenfolgeDocument order
XElement.AncestorsAndSelfXElement.AncestorsAndSelf Umgekehrte DokumentreihenfolgeReverse document order
XElement.AttributesXElement.Attributes DokumentreihenfolgeDocument order
XElement.DescendantNodesAndSelfXElement.DescendantNodesAndSelf DokumentreihenfolgeDocument order
XElement.DescendantsAndSelfXElement.DescendantsAndSelf DokumentreihenfolgeDocument order
XNode.AncestorsXNode.Ancestors Umgekehrte DokumentreihenfolgeReverse document order
XNode.ElementsAfterSelfXNode.ElementsAfterSelf DokumentreihenfolgeDocument order
XNode.ElementsBeforeSelfXNode.ElementsBeforeSelf DokumentreihenfolgeDocument order
XNode.NodesAfterSelfXNode.NodesAfterSelf DokumentreihenfolgeDocument order
XNode.NodesBeforeSelfXNode.NodesBeforeSelf DokumentreihenfolgeDocument order

PositionsprädikatePositional Predicates

Innerhalb von XPath-Ausdrücken werden Positionsprädikate bei vielen Achsen in der Dokumentreihenfolge angegeben, aber bei den rückwärts gerichteten Achsen preceding, preceding-sibling, ancestor und ancestor-or-self wird die umgekehrte Dokumentreihenfolge verwendet.Within an XPath expression, positional predicates are expressed in terms of document order for many axes, but are expressed in reverse document order for reverse axes, which are preceding, preceding-sibling, ancestor, and ancestor-or-self. So gibt z. B. der XPath-Ausdruck preceding-sibling::*[1] das unmittelbar vorausgehende nebengeordnete Element zurück,For example, the XPath expression preceding-sibling::*[1] returns the immediately preceding sibling. auch wenn das endgültige Resultset in der Dokumentreihenfolge angegeben wird.This is the case even though the final result set is presented in document order.

Dagegen werden alle Positionsprädikate in LINQ to XML stets in der Reihenfolge der Achse angegeben.By contrast, all positional predicates in LINQ to XML are always expressed in terms of the order of the axis. So wird z. B. bei anElement.ElementsBeforeSelf().ToList()[0] statt des unmittelbar vorausgehenden nebengeordneten Elements das erste untergeordnete Element der Ebene oberhalb des abgefragten Elements zurückgegeben.For example, anElement.ElementsBeforeSelf().ToList()[0] returns the first child element of the parent of the queried element, not the immediate preceding sibling. Ein anderes Beispiel: anElement.Ancestors().ToList()[0] gibt das übergeordnete Element zurück.Another example: anElement.Ancestors().ToList()[0] returns the parent element.

Beachten Sie, dass bei der oben beschriebenen Herangehensweise die gesamte Auflistung materialisiert wird.Note that the above approach materializes the entire collection. Dies ist nicht die effizienteste Art, diese Abfrage zu schreiben.This is not the most efficient way to write that query. Die Abfrage in der dargestellten Form soll lediglich das Verhalten der Positionsprädikate zeigen.It was written in that way to demonstrate the behavior of positional predicates. Dieselbe Abfrage könnte vernünftiger mit der First-Methode geschrieben werden: anElement.ElementsBeforeSelf().First().A more appropriate way to write the same query is to use the First method, as follows: anElement.ElementsBeforeSelf().First().

Wenn Sie für die Suche nach dem unmittelbar vorausgehenden Element LINQ to XML verwenden möchten, müssten Sie den folgenden Ausdruck schreiben:If you wanted to find the immediately preceding element in LINQ to XML, you would write the following expression:

ElementsBeforeSelf().Last()

LeistungsunterschiedePerformance Differences

XPath-Abfragen, die die XPath-Funktionalität in LINQ to XML verwenden, sind nicht so schnell, wie LINQ to XML-Abfragen.XPath queries that use the XPath functionality in LINQ to XML will not perform as well as LINQ to XML queries.

Verfassen von Abfragen im VergleichComparison of Composition

Das Verfassen einer LINQ to XML-Abfrage weist Parallelen mit dem Verfassen eines XPath-Ausdrucks auf, beide haben aber eine sehr unterschiedliche Syntax.Composition of a LINQ to XML query is somewhat parallel to composition of an XPath expression, although very different in syntax.

Wenn Sie z. B. ein Element in einer Variable namens customers haben und in allen untergeordneten Elementen mit dem Namen CompanyName nach einem Element der zweiten Unterebene namens Customer suchen, würden Sie den folgenden XPath-Ausdruck schreiben:For example, if you have an element in a variable named customers, and you want to find a grandchild element named CompanyName under all child elements named Customer, you would write an XPath expression as follows:

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

Die entsprechende LINQ to XML-Abfrage würde wie folgt lauten:The equivalent LINQ to XML query is:

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

Ähnliche Parallelen gibt es auch bei allen anderen XPath-Achsen.There are similar parallels for each of the XPath axes.

XPath-AchseXPath axis LINQ to XML-AchseLINQ to XML axis
child (Standardachse)child (the default axis) XContainer.Elements
parent (..)Parent (..) XObject.Parent
@ (Attributachse)attribute axis (@) XElement.Attribute

oderor

XElement.Attributes
ancestor-Achseancestor axis XNode.Ancestors
ancestor-or-self-Achseancestor-or-self axis XElement.AncestorsAndSelf
descendant (//)descendant axis (//) XContainer.Descendants

oderor

XContainer.DescendantNodes
descendant-or-selfdescendant-or-self XElement.DescendantsAndSelf

oderor

XElement.DescendantNodesAndSelf
following-siblingfollowing-sibling XNode.ElementsAfterSelf

oderor

XNode.NodesAfterSelf
preceding-siblingpreceding-sibling XNode.ElementsBeforeSelf

oderor

XNode.NodesBeforeSelf
followingfollowing Keine direkte Entsprechung.No direct equivalent.
precedingpreceding Keine direkte Entsprechung.No direct equivalent.

Siehe auchSee Also

LINQ to XML für XPath-Benutzer (C#)LINQ to XML for XPath Users (C#)