我需要在网页中显示之前转义 HTML 标记的黑名单。选择性的原因是允许保留格式(正文、斜体、字体等),但不允许保留任何会“破坏”页面的标签(脚本、元等)。
经过一段时间的思考,我想到了两种方法:
- RegEx——几乎每个人都会告诉您,使用 RegEx 来操纵 HTML 是一个坏主意
- HtmlAgilityPack
我认为我最好的(也是唯一的)解决方案是将字符串加载到 HtmlAgilityPack 并递归 循环遍历子节点。对于每个节点,我都会检查它是否在指定的黑名单中。如果是,我将转义打开(如果存在则关闭)节点,然后处理 InnerHtml
.如果它不在列表中,则按原样输出节点,同时仍在处理 InnerHtml
.
因此,给定以下(非常简单的)来源
The quick <b style='padding: 0 25em;'>brown</b> fox <b>jumped <i>over</i> the <meta http-equiv='refresh' /> moon</b>.
我需要以下输出
The quick <b style='padding: 0 25em;'>brown</b> fox <b>jumped <i>over</i> the <meta http-equiv='refresh' /> moon</b>.
经过大量研究,我遇到了一些担忧、问题和障碍。
- 是
HtmlAgilityPack
满足此要求的最佳库是什么? - 递归解决方案是唯一的方法吗?我虽然关于使用
.Descendants()
方法,因为它通过内部递归返回所有节点的展平列表,但这会导致重复的内容。使用上面的示例,<i>over</i>
节点是InnerHtml
的一部分对于第二个 b 节点,但随后也成为后代集合中它自己的节点。 - 我可能缺少正确的方法或属性,但我找不到一种方法来输出 仅 开始和结束标记而不包括 InnerHtml。我的用例是将开始标记(包括所有属性)输出为转义字符串,输出递归处理的 InnerHtml,然后输出转义结束标记。我想我可以通过使用不同的属性(名称、ID、属性等)构建我自己的输出,但我认为这已经可用。
在我看来,该方法看起来像这样
public string EscapeHtmlTags(string value, ICollection<string> tags) {
var doc = new System.Text.StringBuilder();
doc.LoadHtml(doc);
if (tags.Contains(doc.DocumentNode.Name, StringComparer.CurrentCultureIgnoreCase)) {
// output opening tag as escaped string ????
EscapeHtmlTags(doc.DocumentNode.InnerHtml, tags);
// output closing tag as escaped string ????
}
else {
// output opening tag as is ????
EscapeHtmlTags(doc.DocumentNode.InnerHtml, tags);
// output closing tag as is ????
}
}
当然我仍然需要添加错误处理,并且可能以不同的方式处理各种 NodeType,并且可能添加一个 StringBuilder 实例来收集输出,等等......我什至可以采用克隆和替换现有的方法文档中的节点。
有什么想法或想法吗?
最佳答案
关于html - 如何转义字符串中的特定 HTML 标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22260682/