如何将 XPath 与 XElement 或 LINQ 结合使用?

问题描述 投票:0回答:6

考虑以下 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;

但这不起作用。是否可以向

XElement
提供 XPath 查询?我可以使用旧的
System.Xml
框架来做到这一点,执行以下操作:

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

LINQ 命名空间中是否有类似的东西?


更新:

经过一番折腾之后,我找到了一种方法来完成我想做的事情:

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

我仍然有兴趣看看是否有人有更好的解决方案?

.net xml xpath linq-to-xml xelement
6个回答
147
投票

要将 XPath 与 LINQ to XML 结合使用,请为

System.Xml.XPath
添加 using 声明,这会将
System.Xml.XPath.Extensions
的扩展方法引入作用域。

在你的例子中:

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

40
投票

其他人完全合理地建议了如何使用“本机”LINQ to XML 查询来完成您想要的操作。

但是,为了提供大量替代方案,请考虑使用

XPathSelectElement
XPathSelectElements
XPathEvaluate
来针对
XNode
计算 XPath 表达式(它们都是
XNode
上的扩展方法) )。您还可以使用
CreateNavigator
XPathNavigator
创建
XNode

就我个人而言,我非常喜欢直接使用 LINQ to XML API,因为我是 LINQ 的忠实粉丝,但如果您更熟悉 XPath,上述内容可能会对您有所帮助。


14
投票

看,在处理 LINQ to XML 时,为什么不使用 LINQ 来获取实际对象。

后代从整个 XML 中查找每个元素并列出与指定名称匹配的所有对象。因此,在您的情况下,哈希就是它找到的名称。

所以,而不是做

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 我希望这能帮到您。


9
投票

您可以使用 .Element() 方法将元素链接起来形成类似 XPath 的结构。

举个例子:

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

3
投票

我尝试提出一个用于生成 xpath 的 LINQesq 框架。 它允许您使用 C# lambda 表达式来描述 xpath

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


0
投票

答案是“是”和“否”。 这是可能的,但不能使用

XElement
,因为这并不代表整个文档。代表 xml 文档的
XDocument
有一个名为
XPathSelectElement()
的函数就是为了这个目的。

对于像这样的 Xml

<response>
  <status_code>200</status_code>
  <status_txt>OK</status_txt>
  <data>
    <url>http://someurl/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>

您首先需要将其读作

XDocument

XDocument.Parse("xmlcontent..");

//convert from Xelement
var xe = XElement.Parse("xml string data...");
var xd = new XDocument(xe);

然后您可以拨打

XDocument.XPathSelectElement("/response/data/hash")
来获取结果,如下例所示:

void Main()
{
    var xm = @"<response>
  <status_code>200</status_code>
  <status_txt>OK</status_txt>
  <data>
    <url>http://someurl/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>";
    
    var xd = XDocument.Parse(xm);
    xd.XPathSelectElement("/response/data/hash").Dump("element");
    xd.XPathSelectElement("/response/data/hash").Value.Dump("value");

}

注意:

Dump()
是一种方法,
Console.WriteLine()
请在最后替换

输出将如下所示:

© www.soinside.com 2019 - 2024. All rights reserved.