Html Agility Pack - Problema al seleccionar el subnodo

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

Pregunta

Quiero exportar mi plan de ejecución de Asics a iCal y dado que Asics no ofrece este servicio, decidí construir un pequeño raspador para mi uso personal. Lo que quiero hacer es tomar todas las ejecuciones programadas de mi plan y generar un feed de iCal basado en eso. Estoy usando C # y Html Agility Pack.

Lo que quiero hacer es recorrer todas mis ejecuciones programadas (son nodos div). Luego, a continuación, quiero seleccionar algunos nodos diferentes con mis nodos de ejecución. Mi código se ve así:

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

Mi problema es que run.SelectSingleNode("//div[@class='date']").InnerText no selecciona el nodo con la XPath dada dentro del nodo de ejecución dado. Selecciona el primer nodo que coincide con la XPath en todo el documento.

¿Cómo puedo seleccionar el nodo único con la XPath dada dentro del nodo actual?

Gracias.

Actualizar

Intenté actualizar mi cadena XPath a esto:

string date = run.SelectSingleNode(".div[@class='date']").InnerText;

Esto debería seleccionar el elemento <div class="date"></div> dentro del nodo actual, ¿verdad? Bueno, intenté esto pero obtuve este error:

La expresión debe evaluar a un conjunto de nodos. Descripción: se produjo una excepción no controlada durante la ejecución de la solicitud web actual. Revise el seguimiento de la pila para obtener más información sobre el error y dónde se originó en el código.

Detalles de la excepción: System.Xml.XPath.XPathException: La expresión debe evaluar a un conjunto de nodos.

¿Alguna sugerencia?

Respuesta aceptada

Algunas cosas que le ayudarán cuando trabaje con expresiones HtmlAgilityPack y XPath .

Si se run es un HtmlNode , entonces:

  1. run.SelectNodes("//div[@class='date']")
    Se comportará exactamente como doc.DocumentNode.SelectNodes("//div[@class='date']")

  2. run.SelectNodes("./div[@class='date']")
    Le dará todos los nodos <div> que son hijos del nodo de run . No buscará más a fondo, solo en el siguiente nivel de profundidad.

  3. run.SelectNodes(".//div[@class='date']")
    Devolverá todos los nodos <div> con ese atributo de clase, pero no solo al lado del nodo de run , sino que también buscará en profundidad (cada posible descendiente de él)

Tendrá que elegir entre 2. o 3., dependiendo de cuál satisfaga sus necesidades :)


Respuesta popular

En XPATH, // significa todos los hijos y nietos debajo del nodo actual. Por lo tanto, debe crear una expresión XPATH más restrictiva. Si proporciona el HTML real, y lo que está buscando exactamente, podemos ayudarlo a seguir investigando.

Sobre el error que tiene:

.div[@class='date'] no es válido porque . está pegado a div . Podrías usar div[@class='date'] , o ./div[@class='date'] , ./div[@class='date'] div[@class='date'] ./div[@class='date'] que creo que son equivalentes. Esto se debe a . es un hacha XPATH , que es un alias para self y significa "el nodo actual".



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué