使用HtmlAgillityPack解析HTML閱讀選項標記內容

html html-agility-pack select xpath

我正在嘗試使用HtmlAgilityPack來解析HTML,但我遇到了問題。

示例HTML文檔:

<tr>
  <td class="css_lokalita" colspan="4">
    <select id="region" name="region">
      <option value="0"  selected>VÅ¡etky regiony</option>
      <optgroup>Banskobystrický kraj</optgroup>
      <option value="k_1"  style="color: #000000; font-weight:bold;">Banskobystrický kraj</option>
      <option value="1">&nbsp;&nbsp;&nbsp;Banská Bystrica</option>
          .
          .
          .
      <option value="174">&nbsp;&nbsp;&nbsp;CZ - Ústecký kraj</option>
      <option value="175">&nbsp;&nbsp;&nbsp;CZ - Zlínský kraj</option>     
    </select>
  </td>
</tr>

<tr>
  <td class="css_sfotkou"  colspan="4">
    <input type="checkbox" name="foto" value="1" id="foto" />
    <label for="foto">Iba používatelia s fotkou</label>
  </td>
</tr>

<tr>
  <td class="css_miestnost" colspan="4">
    <select name="akt-miest" id="onoffaci">
      <option value="a_0">VÅ¡etci</option>
          .
          .
          .
      <optgroup label="Záľuby a záujmy">
        <option value="m_1419307">&nbsp;&nbsp;&nbsp;Bez Lásky</option>
          .
          .
          .
        <option value="m_1108016">&nbsp;&nbsp;&nbsp;Drum N Bass</option>
      </optgroup>
    </select>
  </td>
</tr>

我需要來自<select name="akt-miest" id="onoffaci">解析值

例如:

<option value="**a_0**">**VÅ¡etci**</option>

我需要得到價值**a_0**和文字**VÅ¡etci**

所以我首先嘗試按ID進行選擇:

var selectNode = htmlDoc.GetElementbyId("onoffaci");

然後使用Xpath選擇所有選項節點。

var nodes = selectNode.SelectNodes("//option");

獲得價值:

foreach (var node in nodes)
{
    string roomName = node.NextSibling.InnerText;
    string roomId = node.Attributes["value"].Value;
    rooms.Add(new Room { RoomId = roomId, RoomName = roomName });
}

但是我從另一個select( <select id="region" name="region"> )獲取值,這個select位於html代碼的頂部。

編輯:

我應用Darin Dimitrov的建議試試這個:

HtmlNode selectNode = htmlDoc.GetElementbyId("onoffaci");

var nodes = selectNode.SelectNodes("option");

foreach (var node in nodes)
{
    string roomName = node.NextSibling.InnerText;
    string roomId = node.Attributes["value"].Value;
    rooms.Add(new Room { RoomId = roomId, RoomName = roomName });
}

return rooms;

我只解析前三個選項元素,因為我認為問題是選擇編組

optgroup標籤。

<select name="akt-miest" id="onoffaci">
  <option value="a_0">VÅ¡etci</option>
  <option value="a_1">Iba prihlásení</option>
  <option value="a_5" selected="selected">Teraz na Pokeci</option>
  <optgroup label="Hlavné miestnosti">
    <option value="m_13">&nbsp;&nbsp;&nbsp;Bez záväzkov</option>
    <option value="m_9">&nbsp;&nbsp;&nbsp;Do pohody</option>
    <option value="m_39">&nbsp;&nbsp;&nbsp;Dámsky klub</option>
  </optgroup>
  .
  .
  .

我嘗試選擇以下所有節點

var nodes = selectNode.SelectNodes("option::*");

但是我收到了這個錯誤: xpath has an invalid token.

我想訪問selectNode的所有子節點:

HtmlNode selectNode = htmlDoc.GetElementbyId("onoffaci");

編輯#2:

這是所有html文件,我需要解析選項標籤。

http://hotfile.com/dl/98442053/577b556/source.html

一般承認的答案

默認情況下,Html Agility Pack將<OPTION>標記視為“空”,這意味著它不需要關閉</OPTION> 。在這種情況下,結束標記被丟棄。您可以使用HtmlNode.ElementFlags集合更改此行為。

這是一個應該做你想做的代碼:

HtmlDocument doc = new HtmlDocument();
HtmlNode.ElementsFlags.Remove("option");
doc.LoadHtml(yourHtml);

foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//select[@id='onoffaci']//option"))
{
    Console.WriteLine("Value=" + node.Attributes["value"].Value);
    Console.WriteLine("InnerText=" + node.InnerText);
    Console.WriteLine();
}

熱門答案

你的XPath表達式:

//option

它是一條絕對路徑:它從根開始遍歷所有樹。

您需要一個相對的XPath表達式:

descendant::option

或速記

.//option

請注意:這是開始路徑的唯一情況.self::node()簡寫)很有用。



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