48

誰かが私を助けてくれることを願っています。

この例のようhtmlに複数を含むドキュメントがあるとしましょう。divs

<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>

HtmlAgilityPackドキュメントを取得するために使用していhtmlます。私が知る必要があるのは、どのようにしてそれぞれのスパンを取得できるかということsearch_hit-divです。

私の最初の考えは次のようなものでした:

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

それぞれdivは、プロパティとして含まれているスパンを持つオブジェクトである必要があります。

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私が使用しているのは、サブノードでの検索ではありません。ドキュメント全体を何度も検索することを意味します。

つまり、ページ全体のスパンを取得するだけで、すでにそのように機能しているということですが、との間には何の関係もありませspansdivsspanつまり、どちらがどのに関連しているかはもうわかりませんdiv

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

どんな助けでも大歓迎です!

4

5 に答える 5

62

を使用する//と、ドキュメントから検索を開始します。

.//現在のノードからすべてを検索するために使用します

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

または、プレフィックスを完全に削除して、直接の子のみを検索します。

 foreach (HtmlAgilityPack.HtmlNode node2 in node.SelectNodes("span[@prop]"))
于 2013-02-21T13:55:06.840 に答える
39

以下は私のために働きます。重要なビットは、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);
}
于 2013-02-21T23:06:38.527 に答える
3

まず、これを見てください:HtmlAgilityPack-サブノードの選択の問題

これがあなたの質問に対する完全に機能する解決策です:

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[@prop='name']はまったく同じであることがわかります。spandiv


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);
}
于 2013-02-22T07:16:33.367 に答える
2

恥ずかしい:)

みなさん正しかったです。

問題を見つけました。このNullReferenceExceptionは私を悩ませ続けたので、私はそれを詳細に調べるためにより多くの時間を費やしました。これらすべてのdivの間に、同じ「class='search-hit'」属性を持つが内部にスパンがない1つのdivがありました。そのため、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);
   }

上記のコードは機能しています。

皆さん、お時間を割いて助けてくれてありがとう!

于 2013-02-22T12:47:08.547 に答える
0

私はそれを使いました。クラス変換ID

  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);  }
于 2016-06-14T07:27:27.707 に答える