3

AngleSharp を使用して一部の HTML を処理し、後でマイニングするために要素のテキスト コンテンツを抽出すると、AngleSharp が HTML タグを取り除く方法に問題が発生しました。たとえば、次のような HTML があります (改行とタブを除く)。

<div id="someID">
    blah, blah, blah, blah
    blah, blah, 
    <ul>
        <li><i>action.</i></li>
        <li><i>Typical, blah, blah, blah</li>
    </ul>
    blah, blah, blah
</div>

ここでの問題は、次を取得したときですTextContent

var content = someDiv.TextContext;

次のようになります。

"...blah, blah, action.Typical blah, blah..."

単語actionTypicalは空白なしでくっつけられています (それらの間にあるのは html タグだけであるため)。action.Typicalこれは、2 つの単語ではなく 1 つの単語として認識されるため、テキスト コンテンツをトークン化する私の努力を台無しにしています。

もちろん、検索と置換 (おそらく正規表現を使用) を実行すること(\S)\.(\S)$1. $2できます。とにかく、それ自体ではあまり役に立たない可能性があります)。複数のドットを含む単語を除外することはできますが、Web アドレスが( なしで) として表示されるか、または のようなメール アドレスが表示される場合があります。www.somecompany.comwwwsomecompanycomwwwcomsomecompany.comwwwsomebody@somecompany.com

これを回避する堅牢な方法はありますか?タグが削除された後、少なくとも 1 つのスペースを保持するには?

4

2 に答える 2

0

既に遭遇したいくつかのシナリオ(自己終了タグなど)を除いて、あなたが説明した方法は機能します。したがって、私は次のことを提案します。

  • テキストノードは文字通り取られます
  • 要素は子ノードを反復処理します。wrt
    • 2 つの隣接する要素がコンテンツを生成する場合、スペースが挿入されます
    • 子ノードがない場合は、要素が特別なもの (br など) かどうかを確認し、代表的な文字列 (改行など) を配置します。
    • それ以外の場合、たとえば、テキスト ノードが要素に隣接している場合、テキストは挿入されません。

したがって、全体として、次の実装で機能するはずです。

String Stringify(INode node)
{
    switch (node.NodeType)
    {
        case NodeType.Text:
            return node.TextContent;

        case NodeType.Element:
            if (node.HasChildNodes)
            {
                var sb = new StringBuilder();
                var isElement = false;

                foreach (var child in node.ChildNodes)
                {
                    var isPreviousElement = isElement;
                    var content = Stringify(child);
                    isElement = child.NodeType == NodeType.Element;

                    if (!String.IsNullOrEmpty(content) && isElement && isPreviousElement)
                    {
                        sb.Append(' ');
                    }

                    sb.Append(content);
                }

                return sb.ToString();
            }

            switch (node.NodeName.ToLowerInvariant())
            {
                case "br": return "\n";
            }

            goto default;

        default:
            return String.Empty;

    }
}

このような実装の利点は、ニーズに合わせて実際に調整できることです。例として、 のようなタグの場合、br改行の代わりにスペースを簡単に出力できます。

于 2016-01-04T15:20:04.997 に答える