【问题标题】:Parse table with HTML Agility Pack使用 HTML 敏捷包解析表
【发布时间】:2012-08-23 11:52:18
【问题描述】:

在下面的 HTML 中,我可以解析 table 元素,但我不知道如何跳过 th 元素。

我只想获取td 元素,但是当我尝试使用时:

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

...我遇到了一个异常。

<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>

我的代码:

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

【问题讨论】:

    标签: c# html-table html-agility-pack


    【解决方案1】:

    此方法使用 LINQ 查询名称为 tdHtmlNode 实例。

    我还注意到您的输出显示为 val|val|(带有尾随管道),此示例使用 string.Join(pipe, array) 作为删除尾随管道的不那么可怕的方法: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(); 
    

    【讨论】:

      【解决方案2】:

      您的 XPath 语法不正确。请尝试:

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

      这将为您提供td 元素的集合,这些元素可以使用foreach 进行迭代。

      【讨论】:

      • 有了这个建议,我得到:1|house|2|door,但我想在下一个“td”下获得“td”。
      猜你喜欢
      • 2010-10-13
      • 1970-01-01
      • 1970-01-01
      • 2010-10-27
      • 1970-01-01
      • 2013-07-20
      • 1970-01-01
      • 2017-06-01
      • 1970-01-01
      相关资源
      最近更新 更多