2013-02-21 6 views
28

誰かが私を助けてくれることを願っています。 HTMLドキュメントを取得するためにHtmlAgilityPackを使用してHtmlAgilityPackとノードとサブノードの選択

<div class="search_hit"> 

    <span prop="name">Richard Winchester</span> 
    <span prop="company">Kodak</span> 
    <span prop="street">Arlington Road 1</span> 

</div> 
<div class="search_hit"> 

    <span prop="name">Ted Mosby</span> 
    <span prop="company">HP</span> 
    <span prop="street">Arlington Road 2</span> 

</div> 

- 私:

Let'sは、私は、この例のように、複数のdivを含むHTML文書を持っていると言います。私が知る必要があるのは、どのように各 "search_hit" -divのスパンを得ることができるかです。各div要素がプロパティとして含まスパンを持つオブジェクトでなければなりません

foreach (HtmlAgilityPack.HtmlNode node in doc.DocumentNode.SelectNodes("//div[@class='search_hit']")) 
{ 
    foreach (HtmlAgilityPack.HtmlNode node2 in node.SelectNodes("//span[@prop]")) 
    { 

    } 
} 

私が最初に考えたのは、このようなものでした。 I.e.

public class Record 
    { 
     public string Name { get; set; } 
     public string company { get; set; } 
     public string street { get; set; } 
    } 

、このリスト

は、満たされなければならない:

public List<Record> Results = new List<Record>(); 

しかし、使用してXPATHの - 私はそれが何をすべきとサブノードで検索を行っていません。これは、文書全体を何度も何度も検索しています。

私はそれがすでにページ全体のスパンを取得しているということを意味しています。しかし、私はスパンとディビジョンの間には関係がありません。手段:どのスパンがどのdivに関連するかはもうわかりません。

誰かが解決策を知っていますか?私はすでにそれを周りに遊んだので、今私は完全に混乱しています:)

助けていただきありがとうございます!

+0

あなたのコードを解析する方法(完全な解決策)については、私の答えを参照してください。 –

答えて

24

私のために、次の作品:現在のノード

foreach (HtmlAgilityPack.HtmlNode node2 in node.SelectNodes(".//span[@prop]")) 

それとも直接の子を検索するための完全に接頭辞をドロップからすべてを検索する

使用.//。重要なビットは、BeniBelaが「SelectNodes」への2番目の呼び出しでドットを追加すると述べたのと同じです。

List<Record> lstRecords=new List<Record>(); 
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//div[@class='search_hit']")) 
{ 
    Record record=new Record(); 
    foreach (HtmlNode node2 in node.SelectNodes(".//span[@prop]")) 
    { 
    string attributeValue = node2.GetAttributeValue("prop", ""); 
    if (attributeValue == "name") 
    { 
     record.Name = node2.InnerText; 
    } 
    else if (attributeValue == "company") 
    { 
     record.company = node2.InnerText; 
    } 
    else if (attributeValue == "street") 
    { 
     record.street = node2.InnerText; 
    } 
    } 
    lstRecords.Add(record); 
} 
42

//を使用すると、文書beginから検索します。

foreach (HtmlAgilityPack.HtmlNode node2 in node.SelectNodes("span[@prop]")) 
+0

これを行うと、node.SelectNodes( "span [@prop]")内のforeach(HtmlAgilityPack.HtmlNode node2)Visual Studioにエラーが発生しています。 –

+0

どのような種類のエラー?あなたは '。/'接頭辞も試してみることができます。 (私は実際にはちょうど推測している) – BeniBela

+0

私は両方を試してみると、両方とも終わっています:NullReferenceException:オブジェクト参照がオブジェクトのインスタンスに設定されていません。 –

2

まず第一に、このを見てみましょう:ここHtml Agility Pack - Problem selecting subnode

は、あなたの質問のための完全な実用的なソリューションです:

IList<Record> results = new List<Record>(); 
foreach (var node in doc.DocumentNode.SelectNodes("//div[@class='search_hit']")) { 
    var record = new Record(); 
    record.Name = node.SelectSingleNode(".//span[@prop='name']").InnerText; 
    record.company = node.SelectSingleNode(".//span[@prop='company']").InnerText; 
    record.street = node.SelectSingleNode(".//span[@prop='street']").InnerText; 
    results.Add(record); 
} 

あなたが質問を読めば、私はあなたを指摘spanノードはdivノードの(直接の)子であるため、./span[@prop='name']を実行することはまったく同じです。


spanのノードは、それらのpropの属性を持っていない、とあなたは、彼らが表示される順序に応じて、それらを割り当てたい場合は、あなたが行うことができます:私に

foreach (var node in doc.DocumentNode.SelectNodes("//div[@class='search_hit']")) { 
    var spanNodes = node.SelectNodes("./span"); 
    var record = new Record(); 
    record.Name = spanNodes[0].InnerText; 
    record.company = spanNodes[1].InnerText; 
    record.street = spanNodes[2].InnerText; 
    results.Add(record); 
} 
2

は恥:)

皆さんは正しいです。

問題が見つかりました。このNullReferenceExceptionは私の気持ちを変えていたので、私は詳細を見るためにもっと時間をかけました。 これらのdivの間には、同じ「class = 'search-hit'」属性を持つdivが1つありますが、スパンは内部にありません。それがなぜ2番目のループでエラーを通過するのか

foreach (HtmlAgilityPack.HtmlNode node in doc.DocumentNode.SelectNodes("//span[@prop]/ancestor::div[@class='search_hit']")) 
    { 
     Record rec = new Record(); 
     foreach (HtmlAgilityPack.HtmlNode node2 in node.SelectNodes(".//span[@prop]")) 
      { 
      } 
      rList.Results.Add(rec); 
    } 

上記のコードは動作しています。

お時間をいただきありがとうございました!

0

私はこれを使用しました。クラスを変換する

HtmlNodeCollection nodes = dokuman.DocumentNode.SelectNodes("//div[@id='search_hit']//span[@prop]"); 


      for (int i = 0; i < nodes .Count; i++) 
     { 
      var record = new Record(); 


       record.Name = links[i].InnerText; results.Add(record); } 
関連する問題