Wiederholen Sie mehrere HTML-Tabellen im HTML Agility Pack

c# html html-agility-pack xpath

Frage

Ich folgte dem Beispiel im folgenden Link und war in der Lage, HTML-Tabelle erfolgreich zu einer Datentabelle zu analysieren.

http://blog.ditran.net/parsing-html-table-to-c-usable-datalist/

Aber ich bin nicht in der Lage, mehrere Tabellen zu analysieren. Wenn ich TR durchquere, haben die ersten TR immer die Spaltennamen und der Rest die Daten in jeder Tabelle. Also verwende ich diese Logik und speichere die Tabellendaten im Wörterbuch und sende sie an meine ToDataTable-Funktion.

Kann mir jemand helfen, wie ich mehrere Tabellen loopen kann und die gleiche Logik implementieren kann?

var tRowList = doc.DocumentNode.SelectNodes("//tr");
foreach (HtmlNode tRow in tRowList)
                    {
                        if (previousRowSpanList.Count > 0)
                        {
                            theDict = previousRowSpanList[0];
                            previousRowSpanList.Remove(theDict);        //remove it off the list
                            isWorkingWithRowSpan = true;
                        }
                        else
                        {
                            theDict = new List<KeyValuePair<string, string>>();
                            isWorkingWithRowSpan = false;
                        }
                        var tCellList = tRow.SelectNodes("td|th");
                        tCelCount = tCellList.Count;
                        if (tCelCount > 0 &&
                        !(tCelCount == 1 && string.IsNullOrEmpty(tCellList[0].InnerText.Trim()))
                        )
                        {
                            //colOrder = 1;
                            IsNullEntireRow = true;
                            for (int colIndex = 0; colIndex < tCelCount; colIndex++)
                            {
                                cell = tCellList[colIndex];
                                ColInnerText = cell.InnerText.Replace("&nbsp;", " ").Trim();
                                if (!string.IsNullOrEmpty(ColInnerText))
                                    IsNullEntireRow = false;

//

 static DataTable ToDataTable(List<List<KeyValuePair<string, string>>> list)
        {
            DataTable result = new DataTable();
            if (list.Count == 0)
                return result;

            result.Columns.AddRange(
        list.First().Select(r => new DataColumn(r.Value)).ToArray()
    );



            list= list.Skip(1).ToArray().ToList();
            list.ForEach(r => result.Rows.Add(r.Select(c => c.Value).Cast<object>().ToArray()));


            return result;

Beispiel HTML:

<table>
<tbody>
<tr><td style="background-color:#A9F5A9;font-weight:bold;" class="center">Node</td><td style="background-color:#A9F5A9;font-weight:bold;" class="center">Logtime</td><td style="background-color:#A9F5A9;font-weight:bold;" class="center">Hardware</td><td style="background-color:#A9F5A9;font-weight:bold;" class="center">Prcstate A</td><td style="background-color:#A9F5A9;font-weight:bold;" class="center">Prcstate B</td><td style="background-color:#A9F5A9;font-weight:bold;" class="center">Cluster</td><td style="background-color:#A9F5A9;font-weight:bold;" class="center">RAID</td><td style="background-color:#A9F5A9;font-weight:bold;" class="center">AD replication A</td><td style="background-color:#A9F5A9;font-weight:bold;" class="center">AD replication B</td><td style="background-color:#A9F5A9;font-weight:bold;" class="center">File replication A</td><td style="background-color:#A9F5A9;font-weight:bold;" class="center">File replication B</td><td style="background-color:#A9F5A9;font-weight:bold;" class="center">hcstart RESULT</td></tr>
<tr><td class="center">DTMSCB1</td><td class="center">2016-08-26 16:40</td><td class="center">APG43L</td><td class="center">active</td><td class="center">passive</td><td class="center">-</td><td class="center">-</td><td class="center">-</td><td class="center">-</td><td class="center">-</td><td class="center">-</td><td style="background-color:#FF0000;color:#FFFFFF;font-weight:bold;" class="center">Not OK</td></tr>
<tr><td class="center">MSC9</td><td class="center">2016-08-26 16:40</td><td class="center">APG40C/4</td><td class="center">passive</td><td class="center">active</td><td class="center">OK</td><td class="center">OK</td><td class="center">OK</td><td class="center">OK</td><td style="background-color:#FF0000;color:#FFFFFF;font-weight:bold;" class="center">Not OK</td><td class="center">OK</td><td class="center">-</td></tr>
</tbody>
</table>


<table>
<tbody>
<tr><td style="background-color:#A9F5A9;" class="center">Node Type</td><td style="background-color:#A9F5A9;" class="center">Node</td><td style="background-color:#A9F5A9;" class="center">Log Time</td><td style="background-color:#A9F5A9;" class="center">New Mon. Alarms</td><td style="background-color:#A9F5A9;" class="center">Mon. Alarms Total</td><td style="background-color:#A9F5A9;" class="center">Other Alarms</td><td style="background-color:#A9F5A9;" class="center">MML</td></tr>
<tr><td class="center">BSC</td><td class="center">BMBSC1</td><td class="center">2016-08-26 16:45</td><td class="center">0</td><td style="background-color:#FF0000;color:#FFFFFF;font-weight:bold;" class="center">46</td><td class="center">445</td><td class="center">OK</td></tr>
<tr><td class="center">BSC</td><td class="center">BMBSC2C</td><td class="center">2016-08-26 16:45</td><td class="center">0</td><td style="background-color:#FF0000;color:#FFFFFF;font-weight:bold;" class="center">27</td><td class="center">609</td><td class="center">OK</td></tr>
<tr><td class="center">BSC</td><td class="center">CYBSC1</td><td class="center">2016-08-26 16:45</td><td style="background-color:#FF0000;color:#FFFFFF;font-weight:bold;" class="center">1</td><td style="background-color:#FF0000;color:#FFFFFF;font-weight:bold;" class="center">45</td><td class="center">665</td><td class="center">OK</td></tr>
<tr><td class="center">BSC</td><td class="center">CYBSC2C</td><td class="center">2016-08-26 16:45</td><td class="center">0</td><td style="background-color:#FF0000;color:#FFFFFF;font-weight:bold;" class="center">30</td><td class="center">849</td><td class="center">OK</td></tr>
<tr><td class="center">MSC-BC</td><td class="center">CYMSCB1</td><td class="center">2016-08-26 16:45</td><td class="center">0</td><td style="background-color:#FF0000;color:#FFFFFF;font-weight:bold;" class="center">38</td><td class="center">283</td><td class="center">OK</td></tr>
<tr><td class="center">BSC</td><td class="center">DTBSC1</td><td class="center">2016-08-26 16:45</td><td class="center">0</td><td style="background-color:#FF0000;color:#FFFFFF;font-weight:bold;" class="center">48</td><td class="center">201</td><td class="center">OK</td></tr>
<tr><td class="center">BSC</td><td class="center">DTBSC2</td><td class="center">2016-08-26 16:45</td><td style="background-color:#FF0000;color:#FFFFFF;font-weight:bold;" class="center">1</td><td style="background-color:#FF0000;color:#FFFFFF;font-weight:bold;" class="center">31</td><td class="center">310</td><td class="center">OK</td></tr>
<tr><td class="center">MSC-BC</td><td class="center">DTMSCB1</td><td class="center">2016-08-26 16:45</td><td class="center">0</td><td style="background-color:#FF0000;color:#FFFFFF;font-weight:bold;" class="center">25</td><td class="center">130</td><td class="center">OK</td></tr>
<tr><td class="center">HLR</td><td class="center">HLR1</td><td class="center">2016-08-26 16:45</td><td class="center">0</td><td style="background-color:#FF0000;color:#FFFFFF;font-weight:bold;" class="center">16</td><td class="center">12</td><td class="center">OK</td></tr>
<tr><td class="center">HLR</td><td class="center">HLR2</td><td class="center">2016-08-26 16:45</td><td class="center">0</td><td style="background-color:#FF0000;color:#FFFFFF;font-weight:bold;" class="center">24</td><td class="center">10</td><td class="center">OK</td></tr>
<tr><td class="center">MSC-S</td><td class="center">MSC10</td><td class="center">2016-08-26 16:45</td><td class="center">0</td><td style="background-color:#FF0000;color:#FFFFFF;font-weight:bold;" class="center">48</td><td class="center">79</td><td class="center">OK</td></tr>
<tr><td class="center">MSC-S</td><td class="center">MSC9</td><td class="center">2016-08-26 16:45</td><td class="center">0</td><td style="background-color:#FF0000;color:#FFFFFF;font-weight:bold;" class="center">46</td><td class="center">131</td><td class="center">OK</td></tr>
</tbody>
</table>

Akzeptierte Antwort

Ich behalte die erste Antwort als Referenz, aber unten ist eine Methode, die den ursprünglichen HTML-Code in ein String-Array aufteilt, wobei jedes String-Element den HTML-Code für eine Tabelle enthält:

public static string[] ParseHtmlSplitTables(string htmlString)
{
    string[] result = new string[] { };

    if (!String.IsNullOrWhiteSpace(htmlString))
    {
        HtmlDocument doc = new HtmlDocument();
        doc.LoadHtml(htmlString);

        var tableNodes = doc.DocumentNode.SelectNodes("//table");
        if (tableNodes != null)
        {
            result = Array.ConvertAll<HtmlNode, string>(tableNodes.ToArray(), n => n.OuterHtml);
        }
    }

    return result;
}

Mit dem Ergebnis können Sie dann mit der Analyse jeder Tabelle fortfahren:

string[] htmlTables = ParseHtmlSplitTables(htmlString);

foreach (string html in htmlTables)
{
    List<List<KeyValuePair<string, string>>> parseResult = ParseHtmlToDataTable(html);

    DataTable dataTable = ToDataTable(parseResult);
}

Beliebte Antwort

Da Sie mehrere HTML-Tabellen DataSet analysieren möchten, sollten Sie ein DataSet mit einer DataTable pro HTML-Tabelle zurückgeben. Wenn Tabellenheader vorhanden sind, fügt der folgende Code der entsprechenden DataTable Spaltennamen hinzu. Die html-Tabellen-ID wird als Name für die DataTable mit der Sie direkt aus dem DataSet zugreifen können:

Methode zum Konvertieren von HTML-Tabellen in ein DataSet :

public static DataSet HtmlTablesToDataset(string html)
{
    var resultDataset = new DataSet();

    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml(html);
    foreach (HtmlNode table in doc.DocumentNode.SelectNodes("//table"))
    {
        var resultTable = new DataTable(table.Id);

        foreach (HtmlNode row in table.SelectNodes("tr"))
        {
            var headerCells = row.SelectNodes("th");
            if (headerCells != null)
            {
                foreach (HtmlNode cell in headerCells)
                {
                    resultTable.Columns.Add(cell.InnerText);
                }
            }

            var dataCells = row.SelectNodes("td");
            if (dataCells != null)
            {
                var dataRow = resultTable.NewRow();
                for (int i=0; i < dataCells.Count; i++)
                {
                    dataRow[i] = dataCells[i].InnerText;
                }

                resultTable.Rows.Add(dataRow);
            }
        }

        resultDataset.Tables.Add(resultTable);
    }

    return resultDataset;
}

Testcode:

var resultDS = HtmlTablesToDataset(html);

foreach(DataTable dt in resultDS.Tables)
{
    Console.WriteLine("Table: " + dt.TableName);

    string line = "";

    foreach (DataColumn col in dt.Columns)
    {
        line += col.ToString() + " ";
    }
    Console.WriteLine(line.Trim());

    foreach (DataRow row in dt.Rows)
    {
        line = "";
        foreach (DataColumn col in dt.Columns)
        {
            line += row[col].ToString() + " ";
        }

        Console.WriteLine(line.Trim());
    }
}

Beispiel-HTML:

string html =
@"
<html>
    <head>
        <title>Test</title>
    </head>
    <body>
        <table id='t1'>
            <tr>
                <th>Col1</th>
                <th>Col2</th>
            </tr>
            <tr>
                <td>1</td>
                <td>2</td>
            </tr>
            <tr>
                <td>3</td>
                <td>4</td>
            </tr>
        </table>
        <table id='t2'>
            <tr>
                <th>Col1</th>
                <th>Col2</th>
            </tr>
            <tr>
                <td>5</td>
                <td>6</td>
            </tr>
            <tr>
                <td>7</td>
                <td>8</td>
            </tr>        
        </table>
    </body>
</html>                
";


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