Pourquoi cela sélectionne-t-il tous mes éléments <li>
dans mon document?
HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load(url);
var travelList = new List<Page>();
var liOfTravels = doc.DocumentNode.SelectSingleNode("//div[@id='myTrips']")
.SelectNodes("//li");
Ce que je veux, c'est obtenir tous les éléments <li>
dans le <div>
avec une id
de "myTrips".
C'est un peu déroutant parce que vous vous attendez à ce qu'il fasse un selectNodes uniquement sur le div portant l'id "myTrips". Toutefois, si vous faites un autre SelectNodes ("// li"), il effectuera une autre recherche à partir du haut du document.
J'ai corrigé cela en combinant la déclaration en une seule déclaration, mais cela ne fonctionnerait que sur une page Web contenant un seul div portant un identifiant "mytrips". La requête ressemblerait à ceci:
doc.DocumentNode.SelectNodes ("// div [@ id = 'myTrips'] // li");
var liOfTravels = doc.DocumentNode.SelectSingleNode("//div[@id='myTrips']")
.SelectNodes(".//li");
Notez le point dans la deuxième ligne. À cet égard, HTMLAgitilityPack repose entièrement sur la syntaxe XPath, mais le résultat n’est pas intuitif, car ces requêtes sont en réalité les mêmes:
doc.DocumentNode.SelectNodes("//li");
some_deeper_node.SelectNodes("//li");
La création d'un nouveau nœud peut être bénéfique dans certaines situations et vous permet d'utiliser les xpath de manière plus intuitive. J'ai trouvé cela utile dans quelques endroits.
var myTripsDiv = doc.DocumentNode.SelectSingleNode("//div[@id='myTrips']");
var myTripsNode = HtmlNode.CreateNode(myTripsDiv.InnerHtml);
var liOfTravels = myTripsNode.SelectNodes("//li");
Vous pouvez le faire avec une requête 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"));
}
J'espère que ça aide
Cela me semble aussi contre-intuitif, si vous exécutez une méthode selectNodes sur un nœud particulier, je pensais que cela ne ferait que rechercher des éléments situés sous ce nœud, pas dans le document en général.
Quoi qu'il en soit OP si vous modifiez cette ligne: var liOfTravels = doc.DocumentNode.SelectSingleNode ("// div [@ id = 'myTrips']"). SelectNodes ("// li");
À: var liOfTravels = doc.DocumentNode.SelectSingleNode ("// div [@ id = 'myTrips']"). SelectNodes ("li");
Je pense que ça va aller, je viens d'avoir le même problème et cela a résolu le problème pour moi. Je ne sais pas si le li doit être un enfant direct du noeud que vous avez.