Partager via


Comparaison de XPath et LINQ to XML

XPath et LINQ to XML sont similaires d’une certaine manière. Tous deux peuvent être utilisés pour interroger une arborescence XML et retourner des résultats tels qu'une collection d'élément, une collection d'attributs, une collection de nœuds ou la valeur d'un élément ou 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 peut uniquement retourner des collections de nœuds de l’arborescence, tandis que LINQ to XML peut exécuter une requête et projeter un graphique d’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 de manière isolée dans une chaîne. Le compilateur C# ne peut pas contribuer à l’analyse de l’expression XPath au moment de la compilation. En revanche, c’est lui qui analyse et compile les requêtes LINQ to XML. Le compilateur peut intercepter de nombreuses erreurs de requête.

Les résultats XPath ne sont pas fortement typés. Dans certaines circonstances, le résultat de l'évaluation d'une expression XPath est un objet et il incombe au développeur de déterminer le type correct et de convertir le résultat si nécessaire. En revanche, les projections à partir d’une requête LINQ to XML sont fortement typées.

Ordonnancement des résultats

La Recommandation XPath 1.0 stipule qu'une collection qui est le résultat 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. Cela est valable même lors de l'accès à des axes XPath où les prédicats sont exprimés dans l'ordre inverse du document, par exemple 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 collection pour chacun d’eux :

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

Prédicats de position

Dans une expression XPath, les prédicats de position sont exprimés dans l'ordre du document pour de nombreux axes, mais dans l'ordre inverse du document pour les axes inversés. 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. C'est le cas même si le jeu de résultats final est présenté dans l'ordre du document.

Par contraste, tous les prédicats de position dans LINQ to XML sont toujours exprimés dans l'ordre de l'axe. Par exemple, anElement.ElementsBeforeSelf().ElementAt(0) retourne le premier élément enfant du parent de l'élément interrogé, mais pas l'enfant qui précède. Autre exemple : anElement.Ancestors().ElementAt(0) retourne l'élément parent.

Si vous souhaitez rechercher l’élément qui précède dans LINQ to XML, vous devez écrire l’expression suivante :

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

Différences en matière 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 trouver un élément petit-enfant CompanyName sous tous les éléments enfants nommés Customer, vous devez écrire une expression XPath comme suit :

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

La requête LINQ to XML équivalente est :

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 (l'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 des descendants (//) XContainer.Descendants

ou

XContainer.DescendantNodes
descendant-or-self XElement.DescendantsAndSelf

ou

XElement.DescendantNodesAndSelf
frère suivant XNode.ElementsAfterSelf

ou

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

ou

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