それが閉じていないHTMLタグがあるときHtmlAgilityPackで問題を修正することは可能でしょうか?

StackOverflow https://stackoverflow.com/questions/1928293

  •  20-09-2019
  •  | 
  •  

質問

さて、私は次のような問題があります。
私が持っているHTMLは不正な形式であり、私はこれが事実であるとき、HTML敏捷性パックを使用してノードを選択すると問題を抱えている。
以下のコードは次のとおりです。

string strHtml = @"
<html>
  <div>
    <p><strong>Elem_A</strong>String_A1_2 String_A1_2</p>
    <p><strong>Elem_B</strong>String_B1_2 String_B1_2</p>
  </div>
  <div>
    <p><strong>Elem_A</strong>String_A2_2 <String_A2_2> asdas</p>
    <p><strong>Elem_B</strong>String_B2_2 String_B2_2</p>
  </div>
</html>";
HtmlAgilityPack.HtmlDocument objHtmlDocument = new HtmlAgilityPack.HtmlDocument();
objHtmlDocument.LoadHtml(strHtml);
HtmlAgilityPack.HtmlNodeCollection colnodePs = objHtmlDocument.DocumentNode.SelectNodes("//p");
List<string> lststrText = new List<string>();
foreach (HtmlAgilityPack.HtmlNode nodeP in colnodePs)
{
  lststrText.Add(nodeP.InnerHtml);
}

問題はString_A2_2が括弧で囲まれていることである。
そのhtmlagilityパックはlststrTextで5弦の代わりに4を返します。
それはようhtmlagilityパックリターン素子3を聞かせすることが可能です "<strong>Elem_A</strong>String_A2_2 <String_A2_2> asdas"
または多分私は要素を閉じるために、いくつかの前処理を行うことができますか?
lststrTextの現在のコンテンツがある

lststrText[0] = "<strong>Elem_A</strong>String_A1_2 String_A1_2"  
lststrText[1] = "<strong>Elem_B</strong>String_B1_2 String_B1_2"  
lststrText[2] = ""  
lststrText[3] = ""  
lststrText[4] = "<strong>Elem_B</strong>String_B2_2 String_B2_2"
役に立ちましたか?

解決

ほとんどのHTMLパーサは、ダングリングタグは受け付けておりませんつまり、作業DOMを構築してみてください。彼らはいくつかの方法で変換、またはクローズされます。

ノードのみを選択した場合は、あなたに重要であり、速度とデータの膨大な量は、あなたの代わりに正規表現で、すべての

タグを問題をつかむことができない。

Regex reMatchP = new Regex(@"<(p)>.*?</\1>");
foreach (Match m in reMatchP.Matches(strHtml))
{
   Console.WriteLine(m.Value);
}

この正規表現は、

タグがうまく形成され、閉鎖されていると仮定します。

あなたは、この正規表現をあなたのプログラムで多くのことを実行するようにしている場合は、としてそれを宣言する必要があります:

static Regex reMatchP = new Regex(@"<(p)>.*?</\1>", RegexOptions.Compiled);

[編集:敏捷性パックの変更]

あなたはHtmlDocument.csでPushNodeEnd機能を変更することができますパックHtmlAgilityを使用する場合:

if (HtmlNode.IsCDataElement(CurrentNodeName()))
{
   _state = ParseState.PcData;
   return true;
}

// new code start
if ( !AllowedTags.Contains(_currentnode.Name) )
{
    close = true;
}
// new code end

ここでAllowedTagsは、すべての既知のタグの一覧次のようになります。B、P、BR、スパン、DIVなど

出力はあなたが望むものは100%ではありませんが、十分な多分近い?

<strong>Elem_A</strong>String_A1_2 String_A1_2
<strong>Elem_B</strong>String_B1_2 String_B1_2
<strong>Elem_A</strong>String_A2_2 <ignorestring_a2_2></ignorestring_a2_2> asdas
<strong>Elem_B</strong>String_B2_2 String_B2_2

他のヒント

あなたは何をする TidyNet に使用することができますあなたがほのめかすプリ/ポストプロセッシング。あなたはそれがあなたのケースに適用されるwouldntの理由を説明するためにあなたの答えを編集することはできますか?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top