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