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>
我尝试使用HtmlNode
的Remove
方法,但它也删除我的内容。 有什么build议么?
我根据Oded的build议写了一个algorithm。 这里是。 奇迹般有效。
它删除除strong
, em
, u
和原始文本节点之外的所有标签。
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; }