web-dev-qa-db-ja.com

HTML Agility Pack、ノードからのSelectNodes

なぜこれが私の<li>文書内の要素?

HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load(url);

var travelList = new List<Page>();
var liOfTravels = doc.DocumentNode.SelectSingleNode("//div[@id='myTrips']")
                     .SelectNodes("//li");

私が欲しいのは、すべてを取得することです<li>の要素<div>idが「myTrips」です。

18
thatsIT

Id "myTrips"のdivでのみselectNodesを実行すると予想しているため、少し混乱していますが、別のSelectNodes( "// li")を実行すると、ドキュメントの上部から別の検索が実行されます。

ステートメントを1つにまとめることでこれを修正しましたが、 "mytrips"というIDを持つdivが1つしかないWebページでのみ機能します。クエリは次のようになります。

doc.DocumentNode.SelectNodes( "// div [@ id = 'myTrips'] // li");

16
ChristiaanV
var liOfTravels = doc.DocumentNode.SelectSingleNode("//div[@id='myTrips']")
                 .SelectNodes(".//li");

2行目のドットに注意してください。基本的に、これに関してHTMLAgitilityPackはXPath構文に完全に依存していますが、これらのクエリは事実上同じであるため、結果は直感的ではありません。

doc.DocumentNode.SelectNodes("//li");
some_deeper_node.SelectNodes("//li");
13
greenoldman

新しいノードを作成すると、状況によってはメリットがあり、xpathをより直感的に使用できるようになります。これはいくつかの場所で役に立ちました。

var myTripsDiv = doc.DocumentNode.SelectSingleNode("//div[@id='myTrips']");
var myTripsNode = HtmlNode.CreateNode(myTripsDiv.InnerHtml);
var liOfTravels = myTripsNode.SelectNodes("//li");
5
Rob

これは、Linqクエリで実行できます。

HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load(url);

var travelList = new List<HtmlNode>();
foreach (var matchingDiv in doc.DocumentNode.DescendantNodes().Where(n=>n.Name == "div" && n.Id == "myTrips"))
{
    travelList.AddRange(matchingDiv.DescendantNodes().Where(n=> n.Name == "li"));
}

それが役に立てば幸い

4
vfportero

これは私にとっても直観に反するようです。特定のノードでselectNodesメソッドを実行すると、ドキュメント内ではなく、そのノードの下にあるものだけが検索されると思いました。

とにかく、この行を変更するとOP:var liOfTravels = doc.DocumentNode.SelectSingleNode( "// div [@ id = 'myTrips']")。SelectNodes( "// li");

TO:var liOfTravels = doc.DocumentNode.SelectSingleNode( "// div [@ id = 'myTrips']")。SelectNodes( "li");

私はあなたが大丈夫だと思います、私はちょうど同じ問題を抱えていて、それが私のためにそれを修正しました。 liがノードの直接の子である必要があるかどうかはわかりません。

1
Paul