Pack d'agilité HTML - supprimer les balises indésirables sans supprimer le contenu?

c# html-agility-pack

Question

J'ai vu quelques questions liées ici, mais ils ne parlent pas exactement du même problème que je suis confronté.

Je souhaite utiliser le pack d'agilité HTML pour supprimer les balises indésirables de mon code HTML sans perdre le contenu de ces balises.

Ainsi, par exemple, dans mon scénario, j'aimerais conserver les balises " b ", " i " et " u ".

Et pour une entrée comme:

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

Le HTML résultant devrait être:

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

J'ai essayé d'utiliser la méthode Remove HtmlNode , mais elle supprime aussi mon contenu. Aucune suggestion?

Réponse acceptée

J'ai écrit un algorithme basé sur les suggestions d'Oded. C'est ici. Fonctionne comme un charme.

Il supprime toutes les balises sauf strong nœuds de texte strong , em , u et brut.

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;
}

Réponse populaire

Comment supprimer de manière récursive une liste donnée de balises HTML indésirables dans une chaîne HTML

J'ai pris @mathias answer et amélioré sa méthode d'extension afin que vous puissiez fournir une liste de balises à exclure sous forme de List<string> (par exemple {"a","p","hr"} ). J'ai aussi corrigé la logique pour qu'elle fonctionne correctement de manière récursive:

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;
    }



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi