Paquete de agilidad HTML: ¿eliminar etiquetas no deseadas sin eliminar contenido?

c# html-agility-pack

Pregunta

He visto algunas preguntas relacionadas aquí, pero no hablan exactamente del mismo problema que estoy enfrentando.

Quiero usar el paquete de agilidad HTML para eliminar las etiquetas no deseadas de mi HTML sin perder el contenido de las etiquetas.

Así, por ejemplo, en mi escenario, me gustaría preservar las etiquetas " b ", " i " y " u ".

Y para una entrada como:

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

El HTML resultante debe ser:

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

Intenté usar el método Remove HtmlNode , pero también elimina mi contenido. ¿Alguna sugerencia?

Respuesta aceptada

Escribí un algoritmo basado en las sugerencias de Oded. Aquí está. Funciona de maravilla.

Elimina todas las etiquetas excepto los nodos strong , em , u y de texto sin formato.

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

Respuesta popular

Cómo eliminar de forma recursiva una lista dada de etiquetas html no deseadas de una cadena html

Tomé la respuesta de @mathias y mejoré su método de extensión para que pueda proporcionar una lista de etiquetas para excluir como una List<string> (por ejemplo, {"a","p","hr"} ). También arreglé la lógica para que funcione recursivamente correctamente:

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


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué