Partager via


Comparaison de XPath et LINQ to XML

XPath et LINQ to XML sont similaires d’une certaine manière. Les deux peuvent être utilisés pour interroger une arborescence XML, en retournant des résultats tels qu’une collection d’éléments, une collection d’attributs, une collection de nœuds ou la valeur d’un élément ou d’un attribut. Toutefois, il existe des différences significatives entre les deux options.

Différences entre XPath et LINQ to XML

XPath n’autorise pas la projection de nouveaux types. Il ne peut retourner que des collections de nœuds de l’arborescence, tandis que LINQ to XML peut exécuter une requête et projeter un graphique objet ou une arborescence XML dans une nouvelle forme. Les requêtes LINQ to XML peuvent faire beaucoup plus que les expressions XPath.

Les expressions XPath existent en isolation dans une chaîne. Le compilateur C# ne peut pas aider à analyser l’expression XPath au moment de la compilation. En revanche, les requêtes LINQ to XML sont analysées et compilées par le compilateur C#. Le compilateur peut intercepter de nombreuses erreurs de requête.

Les résultats XPath ne sont pas fortement typés. Dans un certain nombre de cas, le résultat de l’évaluation d’une expression XPath est un objet, et c’est au développeur de déterminer le type approprié et de convertir le résultat selon les besoins. En revanche, les projections à partir d’une requête LINQ to XML sont fortement typées.

Classement des résultats

La recommandation XPath 1.0 indique qu’une collection résultant de l’évaluation d’une expression XPath n’est pas ordonnée.

Toutefois, lors de l’itération d’une collection retournée par une méthode d’axe XPath LINQ to XML, les nœuds de la collection sont retournés dans l’ordre du document. C’est le cas même lors de l’accès aux axes XPath où les prédicats sont exprimés en termes d’ordre de document inverse, comme preceding et preceding-sibling.

En revanche, la plupart des axes LINQ to XML retournent des collections dans l’ordre des documents. Toutefois, deux d’entre eux, Ancestors et AncestorsAndSelf, retournent des collections dans l’ordre inverse des documents. Le tableau suivant énumère les axes et indique l’ordre de collecte pour chacun d’eux :

Axe LINQ to XML Classement
XContainer.DescendantNodes Ordre des documents
XContainer.Descendants Ordre des documents
XContainer.Elements Ordre des documents
XContainer.Nodes Ordre des documents
XContainer.NodesAfterSelf Ordre des documents
XContainer.NodesBeforeSelf Ordre des documents
XElement.AncestorsAndSelf Ordre inverse des documents
XElement.Attributes Ordre des documents
XElement.DescendantNodesAndSelf Ordre des documents
XElement.DescendantsAndSelf Ordre des documents
XNode.Ancestors Ordre inverse des documents
XNode.ElementsAfterSelf Ordre des documents
XNode.ElementsBeforeSelf Ordre des documents
XNode.NodesAfterSelf Ordre des documents
XNode.NodesBeforeSelf Ordre des documents

Prédicats positionnels

Dans une expression XPath, les prédicats positionnels sont exprimés en termes d’ordre de document pour de nombreux axes, mais sont exprimés dans l’ordre inverse du document pour les axes inverses. Les axes inverses sont les suivants : preceding, preceding-sibling, ancestor, et ancestor-or-self. Par exemple, l'expression XPath preceding-sibling::*[1] retourne le frère qui précède. Il s’agit du cas même si le jeu de résultats final est présenté dans l’ordre du document.

En revanche, tous les prédicats positionnels dans LINQ to XML sont toujours exprimés en termes d’ordre de l’axe. Par exemple, anElement.ElementsBeforeSelf().ElementAt(0) renvoie le premier élément enfant du parent de l'élément en question, et non le frère immédiatement précédent. Autre exemple : anElement.Ancestors().ElementAt(0) retourne l’élément parent.

Si vous souhaitez trouver l’élément précédent immédiatement dans LINQ to XML, vous devez écrire l’expression suivante :

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

Différences de performances

Les requêtes XPath qui utilisent la fonctionnalité XPath dans LINQ to XML seront plus lentes que les requêtes LINQ to XML.

Comparaison de la composition

La composition d’une requête LINQ to XML est similaire à la composition d’une expression XPath, mais la syntaxe est très différente.

Par exemple, si vous avez un élément dans une variable nommée customers, et que vous souhaitez rechercher un élément petit-enfant nommé CompanyName sous tous les éléments enfants nommés Customer, vous devez écrire cette expression XPath :

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

La requête LINQ to XML équivalente est la suivante :

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

Il existe des parallèles similaires pour chacun des axes XPath.

Axe XPath Axe LINQ to XML
enfant (axe par défaut) XContainer.Elements
Parent (..) XObject.Parent
axe des attributs (@) XElement.Attribute

ou

XElement.Attributes
axe des ancêtres XNode.Ancestors
axe ancestor-or-self XElement.AncestorsAndSelf
axe descendant (//) XContainer.Descendants

ou

XContainer.DescendantNodes
descendant ou auto XElement.DescendantsAndSelf

ou

XElement.DescendantNodesAndSelf
frère suivant XNode.ElementsAfterSelf

ou

XNode.NodesAfterSelf
précédent-frère XNode.ElementsBeforeSelf

ou

XNode.NodesBeforeSelf
suivant Aucun équivalent direct.
précédent Aucun équivalent direct.