Analizando html con HTML Agility Pack y Linq

c# html-agility-pack html-parsing linq

Pregunta

Tengo el siguiente HTML

(..)
<tbody>
 <tr>
  <td class="name"> Test1 </td>
  <td class="data"> Data </td>
  <td class="data2"> Data 2 </td>
 </tr>
 <tr>
  <td class="name"> Test2 </td>
  <td class="data"> Data2 </td>
  <td class="data2"> Data 2 </td>
 </tr>
</tbody>
(..)

La información que tengo es el nombre => así que "Test1" y "Test2". Lo que quiero saber es cómo puedo obtener los datos que están en "datos" y "datos2" según el nombre que tengo.

Actualmente estoy usando:

var data =
    from
        tr in doc.DocumentNode.Descendants("tr")
    from   
        td in tr.ChildNodes.Where(x => x.Attributes["class"].Value == "name")
    where
        td.InnerText == "Test1"
    select tr;

Pero obtengo {"Object reference not set to an instance of an object."} Cuando intento buscar en los data

Respuesta aceptada

En cuanto a su intento, tiene dos problemas con su código:

  1. ChildNodes es raro: también devuelve nodos de texto de espacios en blanco, que no tienen atributos de class (no pueden tener atributos, por supuesto).
  2. Como James Walford comentó, los espacios alrededor del texto son significativos, es probable que desee recortarlos.

Con estas dos correcciones, los siguientes trabajos:

var data =
      from tr in doc.DocumentNode.Descendants("tr")
      from td in tr.Descendants("td").Where(x => x.Attributes["class"].Value == "name")
     where td.InnerText.Trim() == "Test1"
    select tr;

Respuesta popular

Esta es la forma de XPATH - hmmm ... parece que todos se han olvidado del poder XPATH y se concentran exclusivamente en C # XLinq, en estos días :-)

Esta función obtiene todos los valores de datos asociados con un nombre:

public static IEnumerable<string> GetData(HtmlDocument document, string name)
{
    return from HtmlNode node in
        document.DocumentNode.SelectNodes("//td[@class='name' and contains(text(), '" + name + "')]/following-sibling::td")
        select node.InnerText.Trim();
}

Por ejemplo, este código volcará todos los datos de 'Prueba2':

    HtmlDocument doc = new HtmlDocument();
    doc.Load(yourHtml);

    foreach (string data in GetData(doc, "Test2"))
    {
        Console.WriteLine(data);
    }


Related

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é