如何实现一个简单的XPath查询(How to implement a simple XPath l

2019-09-20 08:11发布

我们有一个非常简单的实现的XML文件的XLink :

<root xmlns:xlink="http://www.w3.org/1999/xlink">
  <firstChild id="ID1" />
  ...
  <ref xlink:href="#ID1" />
</root>

让我们假设XLink的实施不会得到任何比这更复杂。 然而,最重要的一点是,该元件称为(在这种情况下,则firstChild)可以在文档中出现的任何地方,在任何地方的层次结构。

在XPath查询你会发现通过使用如下的表达式由<REF>节点中提到的元件:

//*[@id='ID1']

什么是用最好的相当于LINQ到XML ? 我不得不沿着这些路线思想的东西:

XDocument doc = XDocument.Load("file.xml");
var dest = xDoc.Descendants().Where(e => (string)e.Attribute("id") == "ID1").SingleOrDefault();

我还没有实际测试过它。 但总的来说,如果XML文档是相当大的,是LINQ的方式将是低效的(因为它的使用上的XDocument所有后代的枚举)? 它会更好恢复到的XPathNavigator,只是使用XPath表达式?

如果这种事情是好的,在LINQ做,有没有比我写的更好的方法? LINQ仍然只有几天大,我...这是真棒,但我不知道是否有一定的操作效率的局限性。

Answer 1:

XPathNavigator不会是任何更有效的在这里,因为它仍然会枚举所有的后代找到他们-有没有神奇的灰尘存在。 如果你希望它是比这更有效的,你需要一个指标,并没有内置XML API为他们提供开箱即用的,所以你必须推出自己的。 例如:

XDocument doc = ...;
var id2elem = (from e in doc.Descendants()
               let id = e.Attribute("id")
               where id != null
               select new { Id = id.Value, Element = e })
              .ToDictionary(kv => kv.Id, kv => kv.Element);

然后使用该词典由ID,当您需要查找的节点。 很显然,这仅仅是值得的,如果查询比较频繁,而不是如果你只是需要做一次或两次。



Answer 2:

如果我是你,我会做同样的方式。 除了在where子句中:

from e in xDoc.Descendants()
let id = e.Attribute("id") ? e.Attribute("id").Value : null
where (id == "ID")
select e

因此,有没有必要做类型转换。

关于你的第一个问题,据我所知,微软停止对XPath实现发展,所以我相信,即使此刻没有,LINQ到XML将具有比XPath的一个更好的优化。



Answer 3:

from e in doc.Descendants()
where (string)e.Attribute("id") != null
select e;


文章来源: How to implement a simple XPath lookup