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:
my paragraph
are italic and bold
Le HTML résultant devrait être:
my paragraph and my div are italic and bold
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 ssortingng RemoveUnwantedTags(ssortingng data) { if(ssortingng.IsNullOrEmpty(data)) return ssortingng.Empty; var document = new HtmlDocument(); document.LoadHtml(data); var acceptableTags = new Ssortingng[] { "strong", "em", "u"}; var nodes = new Queue(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
(par exemple {"a","p","hr"}
). J’ai aussi corrigé la logique pour qu’elle fonctionne correctement de manière récursive:
public static ssortingng RemoveUnwantedHtmlTags(this ssortingng html, List unwantedTags) { if (Ssortingng.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(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; }
Essayez ce qui suit, vous trouverez peut-être un peu plus simple que les autres solutions proposées:
public static int RemoveNodesButKeepChildren(this HtmlNode rootNode, ssortingng 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() { ssortingng html = "my paragraph
and my div are italic and bold"; HtmlDocument document = new HtmlDocument(); document.LoadHtml(html); document.DocumentNode.RemoveNodesButKeepChildren("//div"); document.DocumentNode.RemoveNodesButKeepChildren("//p"); return document.DocumentNode.InnerHtml == "my paragraph and my div are italic and bold"; }
Avant de supprimer un nœud, obtenez son parent et son InnerText
, puis supprimez le nœud et réaffectez InnerText
au parent.
var parent = node.ParentNode; var innerText = parent.InnerText; node.Remove(); parent.AppendChild(doc.CreateTextNode(innerText));
Si vous ne souhaitez pas utiliser le pack d’agilité HTML et que vous souhaitez toujours supprimer les balises HTML indésirables, procédez comme indiqué ci-dessous.
public static ssortingng RemoveHtmlTags(ssortingng strHtml) { ssortingng strText = Regex.Replace(strHtml, "<(.|\n)*?>", Ssortingng.Empty); strText = HttpUtility.HtmlDecode(strText); strText = Regex.Replace(strText, @"\s+", " "); return strText; }