使用HTML Agility Pack和Linq解析html

c# html-agility-pack html-parsing linq

我有以下HTML

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

我的信息是name => so“Test1”和“Test2”。我想知道的是如何根據我的名字獲取“data”和“data2”中的數據。

目前我正在使用:

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

但是當我嘗試查看data時,我得到{"Object reference not set to an instance of an object."}

一般承認的答案

至於您的嘗試,您的代碼有兩個問題:

  1. ChildNodes很奇怪 - 它還返回空白文本節點,它們沒有class屬性(當然不能有屬性)。
  2. 正如詹姆斯沃爾福德評論的那樣,文本周圍的空間很重要,你可能想要修剪它們。

通過這兩個更正,以下工作:

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;

熱門答案

這是XPATH方式 - 嗯......每個人似乎都忘記了XPATH的強大功能,專注於C#XLinq,這些天:-)

此函數獲取與名稱關聯的所有數據值:

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

例如,此代碼將轉儲所有“Test2”數據:

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



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因