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. |