使用其他XPath查询过滤XmlNodeList?

时间:2012-04-10 22:47:37

标签: c# xml xpath

我有一个大型XML文档,我使用C#查询内容。我有类似以下内容:

var bookA = xmlDoc.SelectSingleNode("/books/book[yearPublished=2012 and id=123]");
var bookB = xmlDoc.SelectSingleNode("/books/book[yearPublished=2012 and id=456]");
var bookC = xmlDoc.SelectSingleNode("/books/book[yearPublished=2012 and id=789]");

正如您所看到的,每个查询都会重复“yearPublished”上的过滤器,如果我错了请纠正我,重复解析整个书籍列表。拥有如下内容会更有效:

var newBooks = xmlDoc.SelectNodes("/books/book[yearPublished=2012]");
var bookA = newBooks.SelectSingleNode("book[id=123]");
var bookB = newBooks.SelectSingleNode("book[id=456]");
var bookC = newBooks.SelectSingleNode("book[id=789]");

假设我的文档很大(假设它包含有数千本书的数据),我是否更正确根据第一个标准过滤数据然后从过滤列表中选择所需的XmlNode会更有效?

其次,我试图验证我的假设,但我遇到了麻烦。我收到有关SelectSingleNode的错误消息:

  

'System.Xml.XmlNodeList'不包含的定义   'SelectSingleNode'并没有扩展方法'SelectSingleNode'   接受类型为'System.Xml.XmlNodeList'的第一个参数可能是   发现(您是否缺少using指令或程序集引用?)

我有一个System.Xml的引用,也有“使用System.Xml”。我错过了别的什么吗?

3 个答案:

答案 0 :(得分:2)

SelectNodes方法返回XmlNodeList类型。方法SelectSingleNode属于XmlNode类。

你可以这样得到你的书:

var bookA = newBooks.Where(x => x.Attributes["id"].Value == 123);
var bookB = newBooks.Where(x => x.Attributes["id"].Value == 456);
var bookC = newBooks.Where(x => x.Attributes["id"].Value == 789);

答案 1 :(得分:1)

var newBooks = xmlDoc.SelectNodes("/books/book[yearPublished=2012]");

这将返回XmlNodeList个对象。此对象不包含名为SelectSingleNode的方法,这就是编译器告诉您的原因。

您可以迭代XmlNodeList方法返回的SelectNodes中的节点,如下所示:

foreach (XmlNode node in newBooks)
{
   //...
}

至于您的性能问题或感知性能问题,我建议您加载所需大小的文件并对其进行基准测试。只有这样才能判断出是否存在性能问题,因为您将对其进行测量。

答案 2 :(得分:0)

您可以评估包含变量引用的XPath表达式 - 请参阅 XPathExpression.SetContext() this example 如何实现IXsltContextVariable。