web-dev-qa-db-ja.com

Html AgilityPack-サブノードの選択の問題

アシックスのランニングプランをiCalにエクスポートしたいのですが、アシックスはこのサービスを提供していないので、自分用の小さなスクレーパーを作ることにしました。私がやりたいのは、スケジュールされたすべての実行を計画から取得し、それに基づいてiCalフィードを生成することです。 C#とHtml AgilityPackを使用しています。

私がやりたいのは、スケジュールされたすべての実行を繰り返すことです(これらはdivノードです)。次に、実行ノードでいくつかの異なるノードを選択します。私のコードは次のようになります:

_foreach (var run in doc.DocumentNode.SelectSingleNode("//div[@id='scheduleTable']").SelectNodes("//div[@class='pTdBox']"))
{
    number++;
    string date = run.SelectSingleNode("//div[@class='date']").InnerText;
    string type = run.SelectSingleNode("//span[@class='menu']").InnerHtml;
    string distance = run.SelectSingleNode("//span[@class='distance']").InnerHtml;
    string description = run.SelectSingleNode("//div[@class='description']").InnerHtml;
    ViewData["result"] += "Dato: " + date + "<br />";
    ViewData["result"] += "Tyep: " + type + "<br />";
    ViewData["result"] += "Distance: " + distance + "<br />";
    ViewData["result"] += "Description: " + description + "<br />";
    ViewData["result"] += run.InnerHtml.Replace("<", "&lt;").Replace(">", "&gt;") + "<br />" + "<br />" + "<br />";
}
_

私の問題は、run.SelectSingleNode("//div[@class='date']").InnerTextが指定された実行ノード内の指定されたXPathを持つノードを選択しないことです。ドキュメント全体でXPathに一致する最初のノードを選択します。

現在のノード内で指定されたXPathを持つ単一ノードを選択するにはどうすればよいですか?

ありがとうございました。

更新

XPath文字列を次のように更新してみました。

_string date = run.SelectSingleNode(".div[@class='date']").InnerText;
_

これにより、現在のノード内の_<div class="date"></div>_要素が選択されますね。さて、私はこれを試しましたが、このエラーが発生しました:

式はノードセットに評価される必要があります。説明:現在のWebリクエストの実行中に未処理の例外が発生しました。エラーの詳細とコードの発生場所については、スタックトレースを確認してください。

例外の詳細:System.Xml.XPath.XPathException:式はノードセットに評価される必要があります。

助言がありますか?

HtmlAgilityPackおよびXPath式を操作するときに役立ついくつかのこと。

runHtmlNodeの場合、次のようになります。

  1. run.SelectNodes("//div[@class='date']")
    doc.DocumentNode.SelectNodes("//div[@class='date']")とまったく同じように動作します

  2. run.SelectNodes("./div[@class='date']")
    runノードの子であるすべての_<div>_ノードを提供します。次の深度レベルでのみ、より深く検索することはありません。

  3. run.SelectNodes(".//div[@class='date']")
    そのクラス属性を持つすべての_<div>_ノードを返しますが、runノードの隣だけでなく、詳細に検索します(可能な限りその子孫)

ニーズを満たすものに応じて、2。または3.から選択する必要があります:)

58
Oscar Mederos

XPATHで、//は、現在のノードの下にあるすべての子と孫を意味します。したがって、より制限的なXPATH式を考え出す必要があります。実際のHTMLと、正確に探しているものを提供していただければ、さらに掘り下げることができます。

あなたが持っているエラーについて:

.div[@class='date']divに固定されているため、.は無効です。 div[@class='date']または./div[@class='date']を使用できます。これは同等だと思います。これは、.XPATH axe であり、これはselfのエイリアスであり、「現在のノード」を意味するためです。

3
Simon Mourier