如何实现一个简单的XPath查询如何实现、简单、XPath

2023-09-04 05:21:21 作者:打小就傲

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

We have an XML file with a very simple implementation of XLink:

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

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

Let's assume the XLink implementation won't get any more complicated than that. However, the important point is that the element referred to (in this case firstChild) could appear anywhere in the document, anywhere in the hierarchy.

在一个XPath查询,你可以找到该元件称为由&lt;参考>节点通过使用前pression这样的:

In an XPath lookup you could find the element referred to by the <ref> node by using an expression like:

//*[@id='ID1']

什么是使用的最佳相当于 LINQ&NBSP;到&NBSP; XML ?我还以为这些方针的东西:

What's the best equivalent using LINQ to XML? I'd have thought something along these lines:

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

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

I have not actually tested it yet. But in general terms, if the XML document is quite large, is the LINQ way going to be inefficient (since it's using an enumeration of all descendants on the XDocument)? Would it be better to revert to an XPathNavigator and just use the XPath expression?

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

If this kind of thing is okay to do in LINQ, is there a better method than what I wrote? LINQ is still only a few days old to me... It's awesome, but I wonder if it has efficiency limitations for certain operations.

推荐答案

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

XPathNavigator isn't going to be any more efficient here, because it will still have to enumerate all descendants to find them - there's no magic dust there. If you want it to be more efficient than that, you'll need an index, and no built-in XML API provides them out of the box, so you'll have to roll out your own. For example:

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查找节点,当您需要。很显然,这仅仅是值得的,如果查询比较频繁,而不是如果你只需要一次或两次做到这一点。

and then use that dictionary to lookup nodes by ID whenever you need to. Obviously, this is only worthwhile if lookups are relatively frequent, and not if you just need to do it once or twice.