Holen Sie sich spezifische Tabellen mit Html Agility Pack

c# html-agility-pack xpath

Frage

Ich habe Probleme, bestimmte Tabellen mit HTML Agility Pack zu erhalten. Ich kann den HTML-Code auch nicht ändern, daher kann ich keine anderen IDs oder Klassen oder ähnliches verwenden.

Kann mir jemand zeigen, wie ich auf jede einzelne Tabelle der folgenden zugreifen würde?

<table class="newTable">
      //table 1 contents
    <table border="0" cellpadding="3" cellspacing="2" width="100%">
         //table 1 - A contents
    </table>
</table>
<table border="0" cellpadding="0" cellspacing="0" class="newTable">
     //table 2 contents
    <table width="100%" border="0" cellspacing="2" cellpadding="0">
        //table 2 - A contents
    </table>
    <table width="100%" border="0" cellspacing="2" cellpadding="0">
       //table 2 - B contents
    </table>
    <table width="100%" cellspacing="2" cellpadding="0">
       //table 2 - C contents
    </table>
</table>
<table>
     //table 3 contents
</table>

Gerade jetzt, wenn ich folgendes rufen würde

HtmlNode table = doc.DocumentNode.SelectSingleNode("//table");
foreach (var cell in table.SelectNodes("//tr/td"))
{
     string someVariable = cell.InnerText
}

Ich würde alles durchgehen. Ich möchte auf Tabellen anders zugreifen können, um zu korrelieren, wo ich die Daten speichere.

Ich habe versucht, etwas wie zu betrachten

doc.DocumentNode.SelectNodes("//table[1]");

aber die Verwendung eines Indexes scheint nicht zu funktionieren, wenn ich versuche, eine Tabelle mit ihr anzugeben, liest sie immer noch alle Tabellen oder keine ein.

Gleiches gilt für das, es funktioniert entweder gar nicht oder bekommt alles.

foreach (var cell in table.SelectNodes("//table").Skip(some_number))
{
     string someVariable = cell.InnerText
}

Ich verwende das NuGet-Paket von HTML Agility Pack 1.4.9

BEARBEITEN:

Mein Versuch, NUR Tabelle 1 - A's Inhalt zu bekommen. Beide geben null oder endcodingfound Ausnahmen.

HtmlNode table = doc.DocumentNode.SelectSingleNode("//table/tr/td/table[1]");

HtmlNode table = doc.DocumentNode.SelectSingleNode("//table[1]/tr/td/table[1]");

Akzeptierte Antwort

Der Fehler ist bei Ihrem zweiten Aufruf, der "// tr / td" geht zurück zum Wurzelelement. Ihr Indexer ist die richtige Lösung für den ersten Teil Ihres Problems, der zweite kann behoben werden, indem Sie angeben, dass Sie von wo aus navigieren möchten:

HtmlNode table = doc.DocumentNode.SelectSingleNode("//table[1]");
foreach (var cell in table.SelectNodes(".//tr/td")) // **notice the .**
{
     string someVariable = cell.InnerText
}

Ich bin mir nicht sicher, was sonst noch vorgeht, aber wenn ich die Testtabelle auf diesen Code erweitere , funktioniert das Folgende nur bei meinem Test. Es könnte bedeuten, dass Sie ein wenig mehr Kontext teilen müssen.

Dies ist das Dokument, das ich für die Tests verwendet habe:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <table class="newTable">
        <tr>
            <td>
                <table border="0" cellpadding="3" cellspacing="2" width="100%">
                    <tr><td>
                        //table 1 - A contents
                    </td></tr>
                </table>
            </td>
        </tr>

    </table>
    <table border="0" cellpadding="0" cellspacing="0" class="newTable">
        <tr>
            <td>
                //table 2 contents
                <table width="100%" border="0" cellspacing="2" cellpadding="0">
                    <tr>
                        <td>
                            //table 2 - A contents
                        </td>
                    </tr>
                </table>
                <table width="100%" border="0" cellspacing="2" cellpadding="0">
                    <tr>
                        <td>
                            //table 2 - B contents
                        </td>
                    </tr>
                </table>
                <table width="100%" cellspacing="2" cellpadding="0">
                    <tr>
                        <td>
                            //table 2 - C contents
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
    <table>
        <tr>
            <td>
                //table 3 contents
            </td>
        </tr>
    </table>
</body>
</html>

Und das ist der Code, um die Werte zu extrahieren, nach denen Sie suchen:

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(text);

var node1A = doc.DocumentNode.SelectSingleNode("//table[1]//table[1]");
string content1A = node1A.InnerText;
Console.WriteLine(content1A);

var node2C = doc.DocumentNode.SelectSingleNode("//table[2]//table[3]");
string content2C = node2C.InnerText;
Console.WriteLine(content2C);

Zeigt an:

Bildbeschreibung hier eingeben

Aktualisieren

Ok, ich habe dein aktuelles HTML genommen und bekomme auch eine NullReference. Es muss etwas geben, das das Agility Pack stark verwirrt, nicht sicher warum. Einige Experimente mit der Linq-API scheinen jedoch zu funktionieren, ich hoffe, dass es eine Alternative für Sie sein kann:

var table = doc.DocumentNode.DescendantsAndSelf("table").Skip(1).First().Descendants("table").First();
var tds   = table.Descendants("td");



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum