49

私はここでいくつかの関連する質問を見てきましたが、それらは私が直面している同じ問題について正確に話しているわけではありません。

HTML Agility Packを使用して、タグ内のコンテンツを失うことなく、HTMLから不要なタグを削除したいと思います。

たとえば、私のシナリオでは、タグ「b」、「」、「」iを保持したいと思いますu

そして、次のような入力の場合:

<p>my paragraph <div>and my <b>div</b></div> are <i>italic</i> and <b>bold</b></p>

結果のHTMLは次のようになります。

my paragraph and my <b>div</b> are <i>italic</i> and <b>bold</b>

HtmlNodeのメソッドを使用してみRemoveましたが、コンテンツも削除されます。助言がありますか?

4

5 に答える 5

63

Odedの提案に基づいてアルゴリズムを作成しました。ここにあります。チャームのように機能します。

strong、、および生のテキストノードemを除くすべてのタグを削除します。u

internal static string RemoveUnwantedTags(string data)
{
    if(string.IsNullOrEmpty(data)) return string.Empty;

    var document = new HtmlDocument();
    document.LoadHtml(data);

    var acceptableTags = new String[] { "strong", "em", "u"};

    var nodes = new Queue<HtmlNode>(document.DocumentNode.SelectNodes("./*|./text()"));
    while(nodes.Count > 0)
    {
        var node = nodes.Dequeue();
        var parentNode = node.ParentNode;

        if(!acceptableTags.Contains(node.Name) && node.Name != "#text")
        {
            var childNodes = node.SelectNodes("./*|./text()");

            if (childNodes != null)
            {
                foreach (var child in childNodes)
                {
                    nodes.Enqueue(child);
                    parentNode.InsertBefore(child, node);
                }
            }

            parentNode.RemoveChild(node);

        }
    }

    return document.DocumentNode.InnerHtml;
}
于 2012-10-11T10:00:24.593 に答える
16

不要なhtmlタグの特定のリストをhtml文字列から再帰的に削除する方法

私は@mathiasの回答を受け取り、彼の拡張メソッドを改善して、除外するタグのリストをList<string>(eg {"a","p","hr"})として指定できるようにしました。また、再帰的に適切に機能するようにロジックを修正しました。

public static string RemoveUnwantedHtmlTags(this string html, List<string> unwantedTags)
    {
        if (String.IsNullOrEmpty(html))
        {
            return html;
        }

        var document = new HtmlDocument();
        document.LoadHtml(html);

        HtmlNodeCollection tryGetNodes = document.DocumentNode.SelectNodes("./*|./text()");

        if (tryGetNodes == null || !tryGetNodes.Any())
        {
            return html;
        }

        var nodes = new Queue<HtmlNode>(tryGetNodes);

        while (nodes.Count > 0)
        {
            var node = nodes.Dequeue();
            var parentNode = node.ParentNode;

            var childNodes = node.SelectNodes("./*|./text()");

            if (childNodes != null)
            {
                foreach (var child in childNodes)
                {
                    nodes.Enqueue(child);                       
                }
            }

            if (unwantedTags.Any(tag => tag == node.Name))
            {               
                if (childNodes != null)
                {
                    foreach (var child in childNodes)
                    {
                        parentNode.InsertBefore(child, node);
                    }
                }

                parentNode.RemoveChild(node);

            }
        }

        return document.DocumentNode.InnerHtml;
    }
于 2015-02-03T12:23:47.223 に答える
9

次のことを試してください。他の提案されたソリューションよりも少しきれいに感じるかもしれません。

public static int RemoveNodesButKeepChildren(this HtmlNode rootNode, string xPath)
{
    HtmlNodeCollection nodes = rootNode.SelectNodes(xPath);
    if (nodes == null)
        return 0;
    foreach (HtmlNode node in nodes)
        node.RemoveButKeepChildren();
    return nodes.Count;
}

public static void RemoveButKeepChildren(this HtmlNode node)
{
    foreach (HtmlNode child in node.ChildNodes)
        node.ParentNode.InsertBefore(child, node);
    node.Remove();
}

public static bool TestYourSpecificExample()
{
    string html = "<p>my paragraph <div>and my <b>div</b></div> are <i>italic</i> and <b>bold</b></p>";
    HtmlDocument document = new HtmlDocument();
    document.LoadHtml(html);
    document.DocumentNode.RemoveNodesButKeepChildren("//div");
    document.DocumentNode.RemoveNodesButKeepChildren("//p");
    return document.DocumentNode.InnerHtml == "my paragraph and my <b>div</b> are <i>italic</i> and <b>bold</b>";
}
于 2014-07-23T14:29:53.640 に答える
5

ノードを削除する前に、その親とそのを取得してからInnerText、ノードを削除して、を親に再割り当てしInnerTextます。

var parent = node.ParentNode;
var innerText = parent.InnerText;
node.Remove();
parent.AppendChild(doc.CreateTextNode(innerText));
于 2012-10-08T18:34:37.313 に答える
3

Htmlアジリティパックを使用せずに、以下に示す方法よりも不要なHtmlタグを削除したい場合。

public static string RemoveHtmlTags(string strHtml)
    {
        string strText = Regex.Replace(strHtml, "<(.|\n)*?>", String.Empty);
        strText = HttpUtility.HtmlDecode(strText);
        strText = Regex.Replace(strText, @"\s+", " ");
        return strText;
    }
于 2015-05-04T08:54:14.587 に答える