Html Agility Pack - Problème lors de la sélection du sous-noeud

asp.net-mvc c# html-agility-pack

Question

Je souhaite exporter mon plan d'exécution Asics vers iCal et, comme Asics n'offre pas ce service, j'ai décidé de construire un petit racleur pour mon usage personnel. Ce que je veux faire, c'est prendre toutes les exécutions planifiées de mon plan et générer un flux iCal basé sur cela. J'utilise C # et Html Agility Pack.

Ce que je veux faire, c'est parcourir toutes mes exécutions planifiées (ce sont des nœuds div). Ensuite, je souhaite sélectionner quelques nœuds différents avec mes nœuds d'exécution. Mon code ressemble à ceci:

foreach (var run in doc.DocumentNode.SelectSingleNode("//div[@id='scheduleTable']").SelectNodes("//div[@class='pTdBox']"))
{
    number++;
    string date = run.SelectSingleNode("//div[@class='date']").InnerText;
    string type = run.SelectSingleNode("//span[@class='menu']").InnerHtml;
    string distance = run.SelectSingleNode("//span[@class='distance']").InnerHtml;
    string description = run.SelectSingleNode("//div[@class='description']").InnerHtml;
    ViewData["result"] += "Dato: " + date + "<br />";
    ViewData["result"] += "Tyep: " + type + "<br />";
    ViewData["result"] += "Distance: " + distance + "<br />";
    ViewData["result"] += "Description: " + description + "<br />";
    ViewData["result"] += run.InnerHtml.Replace("<", "&lt;").Replace(">", "&gt;") + "<br />" + "<br />" + "<br />";
}

Mon problème est que run.SelectSingleNode("//div[@class='date']").InnerText ne sélectionne pas le noeud avec le XPath donné dans le noeud d'exécution donné. Il sélectionne le premier nœud correspondant au XPath dans l'ensemble du document.

Comment puis-je sélectionner le nœud unique avec le XPath donné dans le nœud actuel?

Je vous remercie.

Mettre à jour

J'ai essayé de mettre à jour ma chaîne XPath à ceci:

foreach (var run in doc.DocumentNode.SelectSingleNode("//div[@id='scheduleTable']").SelectNodes("//div[@class='pTdBox']"))
{
    number++;
    string date = run.SelectSingleNode("//div[@class='date']").InnerText;
    string type = run.SelectSingleNode("//span[@class='menu']").InnerHtml;
    string distance = run.SelectSingleNode("//span[@class='distance']").InnerHtml;
    string description = run.SelectSingleNode("//div[@class='description']").InnerHtml;
    ViewData["result"] += "Dato: " + date + "<br />";
    ViewData["result"] += "Tyep: " + type + "<br />";
    ViewData["result"] += "Distance: " + distance + "<br />";
    ViewData["result"] += "Description: " + description + "<br />";
    ViewData["result"] += run.InnerHtml.Replace("<", "&lt;").Replace(">", "&gt;") + "<br />" + "<br />" + "<br />";
}

Cela devrait sélectionner l'élément <div class="date"></div> dans le nœud actuel, non? Eh bien, j'ai essayé ceci mais j'ai eu cette erreur:

L'expression doit être évaluée à un ensemble de nœuds. Description: une exception non gérée s'est produite lors de l'exécution de la demande Web en cours. Consultez la trace de la pile pour plus d'informations sur l'erreur et son origine dans le code.

Détails des exceptions: System.Xml.XPath.XPathException: L'expression doit correspondre à un ensemble de nœuds.

Aucune suggestion?

Réponse acceptée

Quelques éléments qui vous aideront à utiliser les expressions HtmlAgilityPack et XPath .

Si run est un HtmlNode , alors:

  1. run.SelectNodes("//div[@class='date']")
    Va se comporter exactement comme doc.DocumentNode.SelectNodes("//div[@class='date']")

  2. run.SelectNodes("./div[@class='date']")
    Vous donnera tous les nœuds <div> qui sont les enfants du nœud d' run . La recherche ne sera pas plus profonde, mais uniquement au niveau de profondeur suivant.

  3. run.SelectNodes(".//div[@class='date']")
    Renverra tous les nœuds <div> avec cet attribut de classe, mais pas seulement à côté du nœud d' run , mais recherchera également en profondeur

Vous devrez choisir entre 2. ou 3. En fonction de celui qui répond à vos besoins :)


Réponse populaire

Dans XPATH, // désigne tous les enfants et petits-enfants situés sous le nœud actuel. Vous devez donc trouver une expression XPATH plus restrictive. Si vous fournissez le code HTML réel et ce que vous recherchez exactement, nous pouvons vous aider à creuser davantage.

À propos de l'erreur que vous avez:

.div[@class='date'] n'est pas valide car . est collé à div . Vous pouvez utiliser div[@class='date'] ou ./div[@class='date'] ce qui, à mon avis, est équivalent. C'est parce que . est un ax XPATH , qui est un alias pour self et signifie "le nœud actuel".




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi