Html Agility Pack, SelectNodes из node
Почему это отображает все мои элементы <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");
Я хочу получить все <li>
элементы в <div>
с id
из myTrips.
Ответы
Ответ 1
Это немного сбивает с толку, потому что вы ожидаете, что он будет делать selectNodes только для div с id "myTrips", однако если вы сделаете другой SelectNodes ( "//li" ), он выполнит другой поиск с вершины документ.
Я исправил это, объединив инструкцию в одну, но это будет работать только на веб-странице, где у вас есть только один div с идентификатором "mytrips". Запрос будет выглядеть следующим образом:
doc.DocumentNode.SelectNodes( "//div [@id = 'myTrips']//li" );
Ответ 2
var liOfTravels = doc.DocumentNode.SelectSingleNode("//div[@id='myTrips']")
.SelectNodes(".//li");
Обратите внимание на точку во второй строке. В основном в этом отношении HTMLAgitilityPack полностью полагается на синтаксис XPath, однако результат неинтуитивный, потому что эти запросы фактически одинаковы:
doc.DocumentNode.SelectNodes("//li");
some_deeper_node.SelectNodes("//li");
Ответ 3
Создание нового node может быть полезным в некоторых ситуациях и позволяет вам использовать xpaths более интуитивно. Я нашел это полезным в нескольких местах.
var myTripsDiv = doc.DocumentNode.SelectSingleNode("//div[@id='myTrips']");
var myTripsNode = HtmlNode.CreateNode(myTripsDiv.InnerHtml);
var liOfTravels = myTripsNode.SelectNodes("//li");
Ответ 4
Вы можете сделать это с помощью запроса 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"));
}
Я надеюсь, что это поможет
Ответ 5
Это похоже на интуитивно понятное мне также, если вы запустите метод selectNodes для определенного node, я думал, что он будет искать материал под этим node, а не в документе вообще.
В любом случае OP, если вы измените эту строку: var liOfTravels = doc.DocumentNode.SelectSingleNode( "//div [@id = 'myTrips']" ). SelectNodes ( "//li" );
TO: var liOfTravels = doc.DocumentNode.SelectSingleNode( "//div [@id = 'myTrips']" ). SelectNodes ( "li" );
Я думаю, вы будете в порядке, у меня была такая же проблема, и я исправил ее для меня. Я не уверен, хотя если бы li должен был быть прямым дочерним элементом node, который у вас есть.