Table d'analyse avec HTML Agility Pack

c# html-agility-pack html-table

Question

Dans le code HTML suivant, je peux analyser l'élément de table , mais je ne sais pas comment sauter les éléments th .

Je veux obtenir uniquement les éléments td , mais lorsque j'essaie d'utiliser:

foreach (HtmlNode cell in row.SelectNodes("td"))

... Je reçois une exception.

<table class="tab03">
  <tbody>
    <tr>
      <th class="right" rowspan="2">first</th>
    </tr>
    <tr>
      <th class="right">lp</th>
      <th class="right">name</th>
    </tr>
    <tr>
      <td class="right">1</td>
      <td class="left">house</td>
    </tr>
    <tr>
      <th class="right" rowspan="2">Second</th>
    </tr>
    <tr>
      <td class="right">2</td>
      <td class="left">door</td>
    </tr>
  </tbody>
</table>

Mon code:

var document = doc.DocumentNode.SelectNodes("//table");
string store = "";

if (document != null)
{
    foreach (HtmlNode table in document)
    {
        if (table != null)
        {
            foreach (HtmlNode row in table.SelectNodes("tr"))
            {
                store = "";
                foreach (HtmlNode cell in row.SelectNodes("th|td"))
                {
                    store = store + cell.InnerText+"|";
                }

                sw.Write(store );
                sw.WriteLine();  
            }
        }
    }
}

sw.Flush();
sw.Close(); 

Réponse acceptée

Cette méthode utilise LINQ pour interroger les instances HtmlNode le nom td .

J'ai également remarqué que votre sortie apparaît sous la forme: val|val| (avec le tuyau de fin), cet exemple utilise string.Join(pipe, array) tant que méthode moins affreuse de supprimer ce tuyau de fin: val|val .

using System.Linq;

// ...

var tablecollection = doc.DocumentNode.SelectNodes("//table");
string store = string.Empty;

if (tablecollection != null)
{
    foreach (HtmlNode table in tablecollection)
    {
        // For all rows with at least one child with the 'td' tag.
        foreach (HtmlNode row in table.DescendantNodes()
            .Where(desc =>
                desc.Name.Equals("tr", StringComparison.OrdinalIgnoreCase) &&
                desc.DescendantNodes().Any(child => child.Name.Equals("td",
                    StringComparison.OrdinalIgnoreCase))))
        {
            // Combine the child 'td' elements into an array, join with the pipe
            // to create the output in 'val|val|val' format.
            store = string.Join("|", row.DescendantNodes().Where(desc =>
                desc.Name.Equals("td", StringComparison.OrdinalIgnoreCase))
                .Select(desc => desc.InnerText));

            // You can probably get rid of the 'store' variable as it's
            // no longer necessary to store the value of the table's
            // cells over the iteration.
            sw.Write(store);
            sw.WriteLine();
        }
    }
}

sw.Flush();
sw.Close(); 

Réponse populaire

Votre syntaxe XPath n'est pas correcte. S'il vous plaît essayez:

HtmlNode cell in row.SelectNodes("//td")

Cela vous donnera la collection d'éléments td qui peuvent être itérés avec foreach .



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