2011-01-21 19 views
3

HTMLを解析するのにHtmlAgilityPackを使用しようとしていますが、問題が発生しています。HtmlAgillityPackで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 }); 
} 

は、しかし、私は、この選択は、HTMLコードの上にある別の選択(<select id="region" name="region">)から値を取得します。

EDITED:

私はダーリンディミトロフのアドバイスを適用し、これを試してみてください。私は問題は選択が

から成るということであると思うので

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; 

私は、最初の3つのつのみのオプション要素を解析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

+0

@ user572844:ソリューションと説明について私の答えを確認してください。 –

答えて

20

デフォルトでは、<OPTION>タグはHtml Agility Packによって "Empty"として扱われます。つまり、</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(); 
} 
+0

こんにちは、私はあなたのコードをしようとするが、それは最初の3つのオプションタグを選択する、多分私はすべてのhtmlファイルを表示していない問題です。私はbottonの私の質問を編集したhtmlファイルです。 –

+0

@ user572844 - OK、他のタグ(optgroup)の下にオプションがあり、それに応じてコードを更新しました。// select [@ id = 'onoffaci']/option by // [@ id = 'onoffaci'] //オプション(ダブルオプション/オプションの前に注意してください) –

+0

Simon Mourier氏に感謝します:) –

0

あなたは使用する必要があります。

selectNode.SelectNodes("option"); 

の代わり:

selectNode.SelectNodes("//option"); 

をしたり、HTMLドキュメントのルートからあなたのXPath式を始めています。

+0

いいえ選択ノードから始めますが、selectタグもoptgroupタグで構成されているので問題があります。 –

1

は、あなたのXPath式:

//option 

それは絶対パスです:それはすべてのツリーはルートから始まるトラバース。

あなたは相対的なXPath式が必要です。メモしています

descendant::option 

または速記

.//option 

を:これは.self::node()速記でパスを開始するだけケースです)は有用である。

関連する問題