Freigeben über


Vergleich von XPath und LINQ to XML

XPath und LINQ to XML sind auf verschiedene Arten ähnlich. Beide können verwendet werden, um eine XML-Struktur abzufragen, z. B. Ergebnisse wie eine Auflistung von Elementen, eine Auflistung von Attributen, eine Auflistung von Knoten oder den Wert eines Elements oder Attributs zurückzugeben. Es gibt jedoch erhebliche Unterschiede zwischen den beiden Optionen.

Unterschiede zwischen XPath und LINQ to XML

XPath lässt keine Projektion neuer Typen zu. Es kann nur Auflistungen von Knoten aus der Struktur zurückgeben, während LINQ to XML eine Abfrage ausführen und ein Objektdiagramm oder eine XML-Struktur in einem neuen Shape projizieren kann. LINQ to XML-Abfragen können viel mehr als XPath-Ausdrücke ausführen.

XPath-Ausdrücke existieren isoliert in einer Zeichenfolge. Der C#-Compiler kann beim Parsen des XPath-Ausdrucks zur Kompilierzeit nicht helfen. LINQ to XML-Abfragen werden dagegen vom C#-Compiler analysiert und kompiliert. Der Compiler kann viele Abfragefehler abfangen.

XPath-Ergebnisse sind nicht stark typisiert. In einer Reihe von Umständen ist das Ergebnis der Auswertung eines XPath-Ausdrucks ein Objekt, und es liegt an dem Entwickler, den richtigen Typ zu bestimmen und das Ergebnis nach Bedarf zu umwandeln. Im Gegensatz dazu sind die Projektionen aus einer LINQ-to-XML-Abfrage stark typisiert.

Ereignisreihenfolge

Die XPath 1.0-Empfehlung gibt an, dass eine Auflistung, die das Ergebnis der Auswertung eines XPath-Ausdrucks ist, ungeordnet ist.

Beim Durchlaufen einer Sammlung, die von einer LINQ to XML-XPath-Achsenmethode zurückgegeben wurde, werden die Knoten in der Sammlung jedoch in der Dokumentreihenfolge zurückgegeben. Dies ist auch der Fall, wenn sie auf die XPath-Achsen zugreifen, bei denen Prädikate in Bezug auf die umgekehrte Dokumentreihenfolge ausgedrückt werden, wie etwa preceding und preceding-sibling.

Im Gegensatz dazu geben die meisten LINQ to XML-Achsen Auflistungen in Dokumentreihenfolge zurück. Zwei von ihnen, Ancestors und AncestorsAndSelf, geben Sammlungen in umgekehrter Dokumentreihenfolge zurück. Die folgende Tabelle listet die Achsen auf und gibt die Sammlungsreihenfolge für jede an:

LINQ to XML-Achse Bestellung
XContainer.DescendantNodes Dokumentreihenfolge
XContainer.Descendants Dokumentreihenfolge
XContainer.Elements Dokumentreihenfolge
XContainer.Nodes Dokumentreihenfolge
XContainer.NodesAfterSelf Dokumentreihenfolge
XContainer.NodesBeforeSelf Dokumentreihenfolge
XElement.AncestorsAndSelf Umgekehrte Dokumentreihenfolge
XElement.Attributes Dokumentreihenfolge
XElement.DescendantNodesAndSelf Dokumentreihenfolge
XElement.DescendantsAndSelf Dokumentreihenfolge
XNode.Vorfahren Umgekehrte Dokumentreihenfolge
XNode.ElementsAfterSelf Dokumentreihenfolge
XNode.ElementsBeforeSelf Dokumentreihenfolge
XNode.NodesAfterSelf Dokumentreihenfolge
XNode.NodesBeforeSelf Dokumentreihenfolge

Positionale Prädikate

Innerhalb von XPath-Ausdrücken werden Positionsprädikate bei vielen Achsen in der Dokumentreihenfolge angegeben, aber bei den rückwärts gerichteten Achsen wird die umgekehrte Dokumentreihenfolge verwendet. Die umgekehrten Achsen sind: preceding, preceding-sibling, , ancestorund ancestor-or-self. So gibt z. B. der XPath-Ausdruck preceding-sibling::*[1] das unmittelbar vorausgehende nebengeordnete Element zurück, Dies ist der Fall, auch wenn das endgültige Resultset in der Dokumentreihenfolge dargestellt wird.

Im Gegensatz dazu werden alle Positions-Prädikate in LINQ to XML immer in Bezug auf die Reihenfolge der Achse ausgedrückt. So wird z. B. bei anElement.ElementsBeforeSelf().ElementAt(0) statt des unmittelbar vorausgehenden nebengeordneten Elements das erste untergeordnete Element der Ebene oberhalb des abgefragten Elements zurückgegeben. Ein weiteres Beispiel: anElement.Ancestors().ElementAt(0) Gibt das übergeordnete Element zurück.

Wenn Sie das unmittelbar vorangehende Element in LINQ to XML finden möchten, schreiben Sie den folgenden Ausdruck:

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

Leistungsunterschiede

XPath-Abfragen, die die XPath-Funktionalität in LINQ to XML verwenden, sind langsamer als LINQ to XML-Abfragen.

Vergleich der Zusammensetzung

Die Zusammensetzung einer LINQ to XML-Abfrage ähnelt der Zusammensetzung eines XPath-Ausdrucks, die Syntax ist jedoch sehr unterschiedlich.

Wenn Sie beispielsweise ein Element in einer Variablen mit dem Namen customers haben und ein zwei Ebenen untergeordnetes Element mit dem Namen CompanyName unter allen untergeordneten Elementen mit dem Namen Customer finden möchten, schreiben Sie diesen XPath-Ausdruck:

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

Die entsprechende LINQ to XML-Abfrage lautet:

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

Es gibt ähnliche Parallelen für jede XPath-Achse.

XPath-Achse LINQ to XML-Achse
child (Standardachse) XContainer.Elements
Elternteil (..) XObject.Parent
@ (Attributachse) XElement.Attribute

oder

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

oder

XContainer.DescendantNodes
Nachfolger oder Selbst XElement.DescendantsAndSelf

oder

XElement.DescendantNodesAndSelf
gleichgeordnete Elemente XNode.ElementsAfterSelf

oder

XNode.NodesAfterSelf
gleichgeordnete Elemente vorangehend XNode.ElementsBeforeSelf

oder

XNode.NodesBeforeSelf
Folgende Keine direkte Entsprechung.
vorhergehend Keine direkte Entsprechung.