Analyser le code HTML avec HTML Agility Pack et Linq

c# html-agility-pack html-parsing linq

Question

J'ai le code HTML suivant

(..)
<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>
(..)

Les informations que j'ai sont le nom => donc "Test1" & "Test2". Ce que je veux savoir, c'est comment puis-je obtenir les données qui se trouvent dans "data" et "data2" en fonction du nom que j'ai.

Actuellement, j'utilise:

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;

Mais j'obtiens {"Object reference not set to an instance of an object."} Lorsque j'essaie de rechercher des data

Réponse acceptée

En ce qui concerne votre tentative, vous avez deux problèmes avec votre code:

  1. ChildNodes est bizarre - il renvoie également des nœuds de texte d'espaces, qui n'ont pas d'attributs de class (ne peuvent pas avoir d'attributs, bien sûr)
  2. Comme l'a commenté James Walford, les espaces autour du texte sont importants, vous voudrez probablement les réduire.

Avec ces deux corrections, les travaux suivants:

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;

Réponse populaire

Voici la méthode XPATH - hmmm ... tout le monde semble avoir oublié la puissance XPATH et se concentrer exclusivement sur C # XLinq, ces jours-ci :-)

Cette fonction obtient toutes les valeurs de données associées à un nom:

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();
}

Par exemple, ce code videra toutes les données 'Test2':

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

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


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