Html Agility Pack: problema nella selezione del nodo secondario

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

Domanda

Voglio esportare il mio piano corrente Asics in iCal e visto che Asics non offre questo servizio, ho deciso di costruire un piccolo raschietto per il mio uso personale. Quello che voglio fare è prendere tutte le esecuzioni pianificate dal mio piano e generare un feed iCal basato su quello. Sto usando C # e Html Agility Pack.

Quello che voglio fare è iterare attraverso tutte le mie esecuzioni pianificate (sono nodi div). Quindi dopo voglio selezionare alcuni nodi diversi con i miei nodi di esecuzione. Il mio codice assomiglia a questo:

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 />";
}

Il mio problema è che run.SelectSingleNode("//div[@class='date']").InnerText non seleziona il nodo con l'XPath specificato all'interno del nodo di esecuzione dato. Seleziona il primo nodo che corrisponde a XPath nell'intero documento.

Come posso selezionare il singolo nodo con l'XPath specificato all'interno del nodo corrente?

Grazie.

Aggiornare

Ho provato ad aggiornare la mia stringa XPath a questo:

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 />";
}

Questo dovrebbe selezionare l'elemento <div class="date"></div> all'interno del nodo corrente, giusto? Bene, ho provato questo ma ho ottenuto questo errore:

L'espressione deve essere valutata su un set di nodi. Descrizione: si è verificata un'eccezione non gestita durante l'esecuzione della richiesta Web corrente. Si prega di rivedere la traccia dello stack per ulteriori informazioni sull'errore e sulla sua origine nel codice.

Dettagli eccezione: System.Xml.XPath.XPathException: l'espressione deve essere valutata su un set di nodi.

Eventuali suggerimenti?

Risposta accettata

Alcune cose che ti aiuteranno quando lavori con HtmlAgilityPack e le espressioni XPath .

Se run è un HtmlNode , quindi:

  1. run.SelectNodes("//div[@class='date']")
    Will si comporterà esattamente come doc.DocumentNode.SelectNodes("//div[@class='date']")

  2. run.SelectNodes("./div[@class='date']")
    Vi darà tutti i nodi <div> che sono figli del nodo di run . Non cercherà più in profondità, solo al prossimo livello di profondità.

  3. run.SelectNodes(".//div[@class='date']")
    Restituirà tutti i nodi <div> con quell'attributo di classe, ma non solo vicino al nodo di run , ma cercherà anche in profondità (ogni possibile discendente di esso)

Dovrai scegliere tra 2 o 3., a seconda di quale soddisfi le tue esigenze :)


Risposta popolare

In XPATH, // indica tutti i bambini e i nipoti sotto il nodo corrente. Quindi devi trovare un'espressione XPATH più restrittiva. Se fornisci il codice HTML reale e quello che stai cercando esattamente, possiamo aiutarti a esplorare ulteriormente.

Circa l'errore che hai:

.div[@class='date'] non è valido perché . è incollato a div . Potresti usare div[@class='date'] , o ./div[@class='date'] che credo equivalga. Questo perché . è un'ascia XPATH , che è un alias per self e significa "il nodo corrente".




Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché