XPath, seleccione múltiples elementos de múltiples nodos en HTML

c# html html-agility-pack xpath

Pregunta

Simplemente no puedo entender esto.

Tengo que buscar en todos los nodos que tienen clases con valores de "item extend featured" (código a continuación). En esas clases, debo seleccionar cada InnerText de <h2 class="itemtitle"> y el valor de href en él, más todos los InnerTexts de <div class="title-additional"> .

<li class="item extend featured">
    <div class="title-box">
        <h2 class="itemtitle">
            <a target="_top" href="www.example.com/example1/example2/exammple4/example4" title="PC Number 1">PC Number 1</a>
        </h2>
        <div class="title-additional">
            <div class="title-km">150 km</div>
            <div class="title-year">2009</div>
            <div class="title-price">250 €</div>
        </div>

La salida debería ser algo como esto:

Title:
href:
Title-km:
Title-year:
Title-Price:
--------------


Title:
href:
Title-km:
Title-year:
Title-Price:
--------------

Entonces, la pregunta es, ¿cómo recorrer todos los nodos de "item extend featured" en html y seleccionar los elementos que necesito arriba de cada nodo?

Según tengo entendido, algo como esto debería funcionar pero se rompe a la mitad.

EDITAR: Me acabo de dar cuenta, hay anuncios en el sitio que comparten exactamente la misma clase y obviamente no tienen los elementos que necesito. Más problemas para pensar.

var items1 = htmlDoc.DocumentNode.SelectNodes("//*[@class='item extend featured']");

foreach (var e in items1)
{
   var test = e.SelectSingleNode(".//a[@target='_top']").InnerText;
   Console.WriteLine(test);
}

Respuesta aceptada

var page = new HtmlDocument();
page.Load(path);
var lists = page.DocumentNode.SelectNodes("//li[@class='item extend featured']");
foreach(var list in lists)
{
    var link = list.SelectSingleNode(".//*[@class='itemtitle']/a");
    string title = link.GetAttributeValue("title", string.Empty);
    string href = link.GetAttributeValue("href", string.Empty);
    string km = list.SelectSingleNode(".//*[@class='title-km']").InnerText;
    string year = list.SelectSingleNode(".//*[@class='title-year']").InnerText;
    string price = list.SelectSingleNode(".//*[@class='title-price']").InnerText;
    Console.WriteLine("Title: %s\r\n href: %s\r\n Title-km: %s\r\n Title-year: %s\r\n Title-Price: %s\r\n\r\n", title, href, km, year, price);
}

Respuesta popular

Lo que estás tratando de lograr requiere múltiples expresiones XPath, ya que no puedes obtener resultados múltiples en diferentes niveles usando una consulta (a menos que uses Union).

Lo que podrías estar buscando es algo similar a esto:

var listItems = htmlDoc.DocumentNode.SelectNodes("//li[@class='item extend featured']");

foreach(var li in listItems) {
    var title = li.SelectNodes("//h2/a/text()");
    var href = li.SelectNodes("//h2/a/@href");
    var title_km = li.SelectNodes("//div[@class='title-additional']/div[@class='title-km']/text()");
    var title_... // other divs
}

Nota: código no probado



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é