将XPath转换为LINQ

3

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

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

此外,在查询中我找不到.//的LINQ版本:
.//div[span/@title='Event group']

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


1
你不能在LINQ中使用XPath吗?https://msdn.microsoft.com/zh-cn/library/bb342176(v=vs.110).aspx - MarcinJuraszek
@MarcinJuraszek 我正在解析HTML,而不是XML(我提出这个问题的原因是因为HtmlAgilityParser不支持Android应用上的XPath,我的开发目标就是Android应用,所以我正在尝试将所有XPath转换为LINQ) - arestifo
HtmlAgilityPack 应该内置支持 LINQ... - code4life
2个回答

2

您的XPath表达式 (//table[@border='1'])[1] 可以大致翻译为下面的LINQ表达式(假设doc是一个XDocument实例):

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翻译留作练习 :)

非常感谢!这正是我所需的。 - arestifo
@user2396873:你在使用HTML Agility Pack吗?它的API与LINQ to XML不同。 - Jeff Mercado

0

与其试图进行逐字逐句的翻译,不如进行实际等效的查询。

该查询是选择跳过第一行和最后一行的行。有更有效的方法来获取它们。

查询的第一部分是选择具有边框的第一个表格。然后跳过第一行,接着取出除了最后一行之外的所有行。没有可靠的方法可以找出最后一行,除非全部取出并计数。

(//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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接