76 votes

Comment utiliser XPath avec XElement ou LINQ ?

Considérons le XML suivant :

<response>
  <status_code>200</status_code>
  <status_txt>OK</status_txt>
  <data>
    <url>http://bit.ly/b47LVi</url>
    <hash>b47LVi</hash>
    <global_hash>9EJa3m</global_hash>
    <long_url>http://www.tumblr.com/docs/en/api#api_write</long_url>
    <new_hash>0</new_hash>
  </data>
</response>

Je cherche un moyen très court d'obtenir uniquement la valeur de l'option <hash> élément. J'ai essayé :

var hash = xml.Element("hash").Value;

Mais ça ne marche pas. Est-il possible de fournir une requête XPath à un fichier XElement ? Je peux le faire avec l'ancien System.Xml en faisant quelque chose comme :

xml.Node("/response/data/hash").Value

Existe-t-il quelque chose comme cela dans un espace de noms LINQ ?


UPDATE :

Après avoir bricolé un peu plus, j'ai trouvé un moyen de faire ce que j'essaie de faire :

var hash = xml.Descendants("hash").FirstOrDefault().Value;

Je serais quand même intéressé de voir si quelqu'un a une meilleure solution ?

134voto

Richard Points 54016

Pour utiliser XPath avec LINQ to XML, ajoutez une déclaration using pour System.Xml.XPath ce qui amènera les méthodes d'extension de System.Xml.XPath.Extensions dans le champ d'application.

Dans votre exemple :

var value = (string)xml.XPathEvaluate("/response/data/hash");

38voto

Jon Skeet Points 692016

D'autres ont suggéré de manière tout à fait raisonnable comment utiliser les requêtes LINQ to XML "natives" pour faire ce que vous voulez.

Toutefois, dans le but de proposer de nombreuses alternatives, envisagez de XPathSelectElement , XPathSelectElements y XPathEvaluate pour évaluer les expressions XPath par rapport à un XNode (ce sont toutes des méthodes d'extension sur XNode ). Vous pouvez également utiliser CreateNavigator pour créer un XPathNavigator pour un XNode .

Personnellement, je suis un grand fan de l'utilisation directe de l'API LINQ to XML, car je suis un grand fan de LINQ, mais si vous êtes plus à l'aise avec XPath, ce qui précède peut vous aider.

14voto

abhishek Points 1746

Vous voyez, lorsque vous traitez avec LINQ to XML, pourquoi ne pas utiliser LINQ pour obtenir l'objet réel.

Descendants trouve chaque élément de l'ensemble du XML et liste tous les objets qui correspondent au nom spécifié. Donc, dans votre cas, hash est le nom qu'il trouve.

Donc, plutôt que de faire

var hash = xml.Descendants("hash").FirstOrDefault().Value;

Je me briserais comme :

var elements = xml.Descendants("hash");
var hash = elements.FirstOrDefault();

if(hash != null)
 hash.Value // as hash can be null when default. 

De cette façon, vous pouvez également obtenir des attributs, des éléments de nœuds, etc.

Consultez cet article pour avoir une idée claire à ce sujet et vous aider. http://www.codeproject.com/KB/linq/LINQtoXML.aspx J'espère que cela vous aidera.

8voto

panpawel Points 171

Vous pouvez utiliser la méthode .Element() pour enchaîner les éléments afin de former une structure de type XPath.

Pour votre exemple :

XElement xml = XElement.Parse(@"...your xml...");
XElement hash = xml.Element("data").Element("hash");

2voto

TGH Points 15623

J'ai essayé de mettre au point un cadre LINQesq pour générer xpath. Il vous permet de décrire xpath à l'aide d'expressions lambda C#.

var xpath = CreateXpath.Where(e => e.TargetElementName == "td" && e.Parent.Name == "tr");

var xpath = CreateXpath.Where(e => e.TargetElementName == "td").Select(e => e.Text);

Je ne suis pas sûr que cela soit utile dans ce contexte, mais vous pouvez trouver de la documentation ici :

http://www.syntaxsuccess.com/viewarticle/how-to-create-xpath-using-linq

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X