2013-02-19 5 views
5

私はこのHtmlの敏捷性パックのループ

<table border="0" cellpadding="0" cellspacing="0" id="table2"> 
    <tr> 
     <th>Name 
     </th> 
     <th>Age 
     </th> 
    </tr> 
     <tr> 
     <td>Mario 
     </td> 
     <th>Age: 78 
     </td> 
    </tr> 
      <tr> 
     <td>Jane 
     </td> 
     <td>Age: 67 
     </td> 
    </tr> 
      <tr> 
     <td>James 
     </td> 
     <th>Age: 92 
     </td> 
    </tr> 
</table> 

のようなテーブルを持っており、それを解析するHTMLの敏捷性パックを使用します。私は無駄にこのコードを試してみました:

foreach (HtmlNode row in doc.DocumentNode.SelectNodes("//table[@id='table2']//tr")) 
{ 
    foreach (HtmlNode col in row.SelectNodes("//td")) 
    { 
     Response.Write(col.InnerText); 
    } 
} 

は私が間違って何をしているのですか?

+2

何が問題なのですか? – GolfWolf

+0

私は不定ループを取得します – mpora

+1

それは私のために働く(まあまあではありません、私はMario/Jane/Jamesが4回繰り返す名前を取得します)。 '// td' _はDocumentNode_から現在のノードのみを選択しているとは限りません。どのバージョンのHtmlAgilityPackを使用していますか? – agentnega

答えて

1

私は完全なXPathを提供する必要がありました。私は@Codaの提案(https://stackoverflow.com/a/3104048/1238850)からのFirebugを使って、完全なXPathを持って、私はこのコードで終わった:

foreach (HtmlNode row in doc.DocumentNode.SelectNodes("/html/body/table/tbody/tr/td/table[@id='table2']/tbody/tr")) 
{ 
    HtmlNodeCollection cells = row.SelectNodes("td"); 
    for (int i = 0; i < cells.Count; ++i) 
    { 
     if (i == 0) 
     { Response.Write("Person Name : " + cells[i].InnerText + "<br>"); } 
     else { 
      Response.Write("Other attributes are: " + cells[i].InnerText + "<br>"); 
     } 
    } 
} 

私はこれよりずっといい書き込むことができます確信しているが、それは今の私のために働いています。

2

tdを直接選択してください。

foreach (HtmlNode col in doc.DocumentNode.SelectNodes("//table[@id='table2']//tr//td")) 
    Response.Write(col.InnerText); 

あなたが本当にtr S別にいくつかの他の処理のために必要がある場合は、代わりに、ドロップ//とは、実行します。

td sがの直接の子である場合のみ動作します。もちろん、
foreach (HtmlNode row in doc.DocumentNode.SelectNodes("//table[@id='table2']//tr")) 
    foreach (HtmlNode col in row.SelectNodes("td")) 
     Response.Write(col.InnerText); 

trしかし、彼らはそうでなければなりませんか?


EDIT:

var cols = doc.DocumentNode.SelectNodes("//table[@id='table2']//tr//td"); 
for (int ii = 0; ii < cols.Count; ii=ii+2) 
{ 
    string name = cols[ii].InnerText.Trim(); 
    int age = int.Parse(cols[ii+1].InnerText.Split(' ')[1]); 
} 

LINQでこれを行うために、より印象的な方法は、おそらくあります。

+0

はい私は2番目の列が数値とテキストが混在しているのがわかるので、各列を処理に使用したいと思います。数。このコードを試してみると、ページはまさに円であり、結果はありません。 – mpora

3

私は、コードを実行したのだが、年齢が無効なHTML使用して定義されているため、正確であるだけ、表示されます。<th></td>(おそらくタイプミスを)。ところで

、コードが唯一のループに単純化することができます。

foreach (var cell in doc.DocumentNode.SelectNodes("//table[@id='table2']/tr/td")) 
{ 
    Response.Write(cell.InnerText); 
} 

ここで私がテストに使用するコードです:http://pastebin.com/euzhUAAh

関連する問題