Как использовать 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