HTML敏捷包 – 删除不需要的标签而不删除内容?

我在这里看到了一些相关的问题,但是他们并没有提到我面临的同样的问题。

我想使用HTML Agility Pack从我的HTML中删除不需要的标签,而不会丢失标签内的内容。

例如,在我的情况下,我想保留标签“ b ”,“ i ”和“ u ”。

对于像这样的input:

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

我尝试使用HtmlNodeRemove方法,但它也删除我的内容。 有什么build议么?

我根据Oded的build议写了一个algorithm。 这里是。 奇迹般有效。

它删除除strongemu和原始文本节点之外的所有标签。

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

如何从htmlstring中recursion地移除不需要的html标签的给定列表

我采取了@mathias的答案,并改进了他的扩展方法,以便您可以提供一个列表作为List<string> (例如{"a","p","hr"} )排除。 我也修正了这个逻辑,以便recursion地正确地工作:

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

尝试以下,你可能会发现它比其他build议的解决scheme有点整齐:

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

在删除一个节点之前,获取它的父节点和它的InnerText ,然后删除这个节点并重新指定InnerText给父节点。

 var parent = node.ParentNode; var innerText = parent.InnerText; node.Remove(); parent.AppendChild(doc.CreateTextNode(innerText)); 

如果您不想使用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; }