Как использовать XPath с XElement или LINQ?

рассмотрим следующий XML:

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

Я ищу очень короткий способ получить только значение <hash> элемент. Я попробовал:

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

но это не работает. Можно ли предоставить запрос XPath к XElement? Я могу сделать это со старшим System.Xml рамки, делая что-то вроде:

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

есть ли что-то подобное в пространстве имен LINQ?


обновление:

после monkeying вокруг с этим еще я нашел способ сделать то, что я пытаюсь сделать:

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

мне все равно было бы интересно узнать, есть ли у кого-нибудь лучшее решение?

5 ответов


для использования XPath с LINQ to XML добавьте объявление using для System.Xml.XPath, это принесет методы расширения System.Xml.XPath.Extensions в область.

в вашем примере:

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

другие вполне разумно предложили, как использовать "родные" запросы LINQ to XML, чтобы делать то, что вы хотите.

однако, в интересах предоставления множества альтернатив, рассмотрим XPathSelectElement, XPathSelectElements и XPathEvaluate для оценки выражений XPath против XNode (Они все методы расширения на XNode). Вы также можете использовать CreateNavigator создать XPathNavigator на XNode.

лично я большой поклонник использования LINQ to XML API напрямую, так как я большой поклонник LINQ, но если вам удобнее с XPath, выше может помочь вам.


см., при работе с LINQ to XML почему бы вам не использовать LINQ для получения фактического объекта.

потомки находят каждый элемент из всего XML и перечисляют все объекты, соответствующие указанному имени. Поэтому в вашем случае hash-это имя, которое он находит.

Так, а не делать

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

Я бы развалился, как:

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

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

таким образом, вы также можете получить атрибуты, элементы узлов и т. д.

проверьте эту статью, чтобы узнать четкое представление об этом, чтобы это помогло. http://www.codeproject.com/KB/linq/LINQtoXML.aspx Надеюсь, это вам поможет.


вы можете использовать .Метод Element () для цепочки элементов для формирования XPath-подобной структуры.

для примера:

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

Я попытался придумать структуру LINQesq для генерации xpath. Он позволяет описывать xpath с помощью лямбда-выражений 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);

Не уверен, что это полезно в этом контексте, но вы можете найти документацию здесь:

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