将 XPath 转换为 LINQ

Translating XPath to LINQ

我在将以下 XPath 查询转换为 LINQ 时遇到问题。我不确定如何处理 position() 方法,因为我找不到 LINQ 等效方法。

(//table[@border='1'])[1]//tr[position() > 1 and position() < last()]

此外,我在查询中找不到 .// 的 LINQ 版本:

.//div[span/@title='Event group']

有人可以帮我翻译这些吗?

您的 XPath (//table[@border='1'])[1] 的这一部分可以大致翻译为以下 LINQ(假设 docXDocument 的一个实例):

doc.Descendants("table")
   .Where(o => (string)o.Attribute("border") == "1")
   .FirstOrDefault()?

而这个表达式 //tr[position() > 1 and position() < last()],大致翻译为:

.Descendants("tr").Where(o => {
    var trs = o.Parent.Elements("tr").ToList();
    var position = trs.IndexOf(o)+1;  //since XPath position index starts from 1
    return position > 1 && position < trs.Count;
})

从上面两个例子,你应该可以看出在LINQ中如何表达//position()@attribute。翻译你的第二个 XPath 留作练习 :)

与其尝试进行字面翻译,不如进行实际等效的查询。

查询正在选择跳过第一行和最后一行的行。有更有效的方法可以做到这一点。

查询的第一部分是选择第一个 table 有边框的。然后跳过第一行,然后除了最后一行之外的所有行。如果不全部计算,就无法可靠地找出最后一个是什么。

(//table[@border='1'])[1]//tr[position() > 1 and position() < last()]
var table = doc.DocumentNode.Descendants("table")
    .Where(e => e.Attributes["border"] == "1")
    .First();
var rows = table.Descendants("tr")
    .Skip(1) // skip the first row
    .ToList();
var result = rows.Take(rows.Count - 1); // take all up to the last

对于另一部分,// 相当于调用 Descendants()

.//div[span/@title='Event group']
var query =
    from d in e.Descendants("div")
    where d.Elements("span").Any(s => s.Attribute["title"] == "Event group")
    select d;