0

HtmlAgilityPackを使用してHTMLページを解析および分析していますが、各ノードの「深さ」(ノードからの距離)を知る必要がありBodyます。例(「深さ」属性は説明のみを目的としています):

<html>
  <head></head>
  <body depth="0"> 
    <div depth="1">
      <ul depth="2">
        <li depth="3">
          <p depth="4">foo</p>
        </li>
        <li depth="3">
          <p depth="4">bar</p>
        </li>
      </ul>
    </div>
  </body>
</html>

私は2つの明白な解決策を避けようとしています:

  • HTMLツリー(DFS、BFSなど)をスキャンし、各ノードの深さを計算して、値を辞書などに保存します。
  • node.ParentNodeに達するまでカウントして、「オンデマンド」で各ノードの深さを計算しますbody

HtmlAgilityPackによって収集された既存のデータを何らかの方法で使用してこれらを回避する方法はありLoadますか?

4

3 に答える 3

3

私の知る限り、AgilityPackはノードの深さを保存しません。

すべてのノードの深さを取得したい場合は、たとえば、ルートノードから開始し、現在のノードの子への再帰呼び出しで深さを増やす再帰メソッドを作成する方が簡単だと仮定します。

単一ノードの深度計算については、プロパティを使用して、この値HtmlNode.XPathのスラッシュ()の数を計算できます。/これがノードの深さになります。あなたの場合、<body>最初にノードの深さを計算してから、目的のノードの深さからこの値を差し引いて、相対的な深さを取得する必要があります。

var bodyDepth = doc.DocumentNode
    .SelectSingleNode("//body")
    .XPath
    .Count(c => c == '/');
var paragraphDepth = doc.DocumentNode
    .SelectSingleNode("//p")
    .XPath
    .Count(c => c == '/');
var result = paragraphDepth - bodyDepth;

これでわかりますが、プロパティ4を反復処理するよりも簡単かどうかはわかりません。ParentNode

于 2012-07-30T14:53:31.387 に答える
1

ビルトインNodeDepth物件などがあるかどうか聞いていますか?ライブラリによって解析されるすべてのノードについて計算すると、ほとんど保証されないオーバーヘッドが発生するため、答えはノーだと確信しています。ノードの深さのカウントは再帰を使用して非常に簡単に実行できるため、デフォルトでそれが含まれるとは思いません。

なぜあなたは明白な解決策を避けたいのですか?

于 2012-07-30T07:33:04.897 に答える
0

HtmlAgilityPackは深さの詳細を提供しません。上記の「/」文字のカウントを使用して、XPath変数から取得できます。詳細を取得するために親に移動する必要はありません。

 foreach (HtmlNode rootNode in document.DocumentNode.Descendants())
            {
                levels.Add(rootNode.XPath.Count(x => x == '/'));
            }

動作するはずです。

于 2014-10-31T06:06:16.773 に答える