Html Agility Pack,从节点选择节点
本文关键字:节点 选择 Agility Pack Html | 更新日期: 2023-09-27 18:34:01
为什么这会在我的文档中选择我所有的<li>
元素?
HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load(url);
var travelList = new List<Page>();
var liOfTravels = doc.DocumentNode.SelectSingleNode("//div[@id='myTrips']")
.SelectNodes("//li");
我想要的是用"myTrips"id
获得<div>
中的所有<li>
元素。
这有点令人困惑,因为您希望它只会在 id 为"myTrips"的div 上执行 selectNodes,但是如果您执行另一个 SelectNodes("//li"),它将从文档顶部执行另一个搜索。
我通过将语句合并为一个来解决此问题,但这仅适用于只有一个div ID 为"mytrips"的网页。查询将如下所示:
.doc。DocumentNode.SelectNodes("//div[@id='myTrips']//li");
var liOfTravels = doc.DocumentNode.SelectSingleNode("//div[@id='myTrips']")
.SelectNodes(".//li");
请注意第二行中的点。基本上在这方面,HTMLAgitilityPack完全依赖于XPath语法,但是结果是不直观的,因为这些查询实际上是相同的:
doc.DocumentNode.SelectNodes("//li");
some_deeper_node.SelectNodes("//li");
在某些情况下,
创建新节点可能会有所帮助,并允许您更直观地使用 xpath。我发现这在几个地方很有用。
var myTripsDiv = doc.DocumentNode.SelectSingleNode("//div[@id='myTrips']");
var myTripsNode = HtmlNode.CreateNode(myTripsDiv.InnerHtml);
var liOfTravels = myTripsNode.SelectNodes("//li");
您可以使用 Linq 查询执行此操作:
HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load(url);
var travelList = new List<HtmlNode>();
foreach (var matchingDiv in doc.DocumentNode.DescendantNodes().Where(n=>n.Name == "div" && n.Id == "myTrips"))
{
travelList.AddRange(matchingDiv.DescendantNodes().Where(n=> n.Name == "li"));
}
我希望它有所帮助
这
对我来说似乎也有悖常理,如果您在特定节点上运行selectNodes
方法,我认为它只会搜索该节点下的内容,而不是在一般文档中。
无论如何,如果您更改此行,则为OP:
var liOfTravels =
doc.DocumentNode.SelectSingleNode("//div[@id='myTrips']").SelectNodes("//li");
自:
var liOfTravels =
doc.DocumentNode.SelectSingleNode("//div[@id='myTrips']").SelectNodes("li");
我想你会没事的,我刚刚遇到了同样的问题,这为我解决了。我不确定 li 是否必须是您拥有的节点的直接子级。