Foreach 不遍历元素
Foreach not iterating through elements
我有一个 HTML 文档,我正在获取基于 class 的元素。获得它们后,我将遍历每个元素并获取更多元素:
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(content);
var rows = doc.DocumentNode.SelectNodes("//tr[contains(@class, 'row')]");
foreach (var row in rows)
{
var name = row.SelectSingleNode("//span[contains(@class, 'name')]").InnerText,
var surname = row.SelectSingleNode("//span[contains(@class, 'surname')]").InnerText,
customers.Add(new Customer(name, surname));
};
但是,以上是遍历行,但总是检索第一行的文本。
XPath 是否错误?
使用 LINQ 怎么样?
var customers = rows.Select(row => new Customer(Name = row.SelectSingleNode("//span[contains(@class, 'name')]").InnerText, Surname = row.SelectSingleNode("//span[contains(@class, 'surname')]").InnerText)).ToList();
这是 XPath 中的常见问题解答。每当您的 XPath 以 /
开头时,它都会忽略 上下文元素 (在本例中由 row
变量引用的元素)。无论上下文如何,它都从根文档节点开始搜索匹配元素。这就是为什么您的 SelectSingleNode()
总是 return 相同的元素,它是整个文档中第一个匹配的元素。
您只需在前面加上一个点 (.
) 使其相对于当前上下文元素即可:
foreach (var row in rows)
{
var name = row.SelectSingleNode(".//span[contains(@class, 'name')]").InnerText,
var surname = row.SelectSingleNode(".//span[contains(@class, 'surname')]").InnerText,
customers.Add(new Customer(name, surname));
}
我有一个 HTML 文档,我正在获取基于 class 的元素。获得它们后,我将遍历每个元素并获取更多元素:
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(content);
var rows = doc.DocumentNode.SelectNodes("//tr[contains(@class, 'row')]");
foreach (var row in rows)
{
var name = row.SelectSingleNode("//span[contains(@class, 'name')]").InnerText,
var surname = row.SelectSingleNode("//span[contains(@class, 'surname')]").InnerText,
customers.Add(new Customer(name, surname));
};
但是,以上是遍历行,但总是检索第一行的文本。
XPath 是否错误?
使用 LINQ 怎么样?
var customers = rows.Select(row => new Customer(Name = row.SelectSingleNode("//span[contains(@class, 'name')]").InnerText, Surname = row.SelectSingleNode("//span[contains(@class, 'surname')]").InnerText)).ToList();
这是 XPath 中的常见问题解答。每当您的 XPath 以 /
开头时,它都会忽略 上下文元素 (在本例中由 row
变量引用的元素)。无论上下文如何,它都从根文档节点开始搜索匹配元素。这就是为什么您的 SelectSingleNode()
总是 return 相同的元素,它是整个文档中第一个匹配的元素。
您只需在前面加上一个点 (.
) 使其相对于当前上下文元素即可:
foreach (var row in rows)
{
var name = row.SelectSingleNode(".//span[contains(@class, 'name')]").InnerText,
var surname = row.SelectSingleNode(".//span[contains(@class, 'surname')]").InnerText,
customers.Add(new Customer(name, surname));
}