如何转义字符串中的特定HTML标记

时间:2014-03-07 21:07:15

标签: html xml html-agility-pack

我需要在显示然后在网页中之前转义HTML标记的黑名单。选择性的原因是允许保留格式(bod,斜体,字体等),但不允许任何会“破坏”页面的标记(脚本,元等)。

在考虑了一段时间后,我提出了两种方法:

  1. RegEx - 正如几乎每个人都会告诉你的那样,使用RegEx操纵HTML是一个坏主意
  2. HtmlAgilityPack
  3. 我认为我最好的(也是唯一的)解决方案是将字符串加载到 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 &lt;meta http-equiv='refresh' /&gt; moon</b>.
    

    经过大量研究后,我遇到了一些问题,问题和障碍。

    1. HtmlAgilityPack是用于此要求的最佳库吗?
    2. 递归解决方案是唯一的方法吗?我虽然使用.Descendants()方法,因为它通过内部递归返回所有节点的扁平列表,但这会导致重复的内容。使用上面的示例,<i>over</i>节点是第二个b节点的InnerHtml的一部分,但后来也成为Descendants集合中自己的节点。
    3. 我可能错过了正确的方法或属性,但我找不到输出只是开始和结束标签而不包含InnerHtml的方法。我的用例是输出开始标记(包括所有属性)作为转义字符串,输出递归处理的InnerHtml,然后输出转义的结束标记。我想我可以通过使用不同的属性(Name,Id,Attributes等)构建我自己的输出,但我认为这已经可用。
    4. 正如我所看到的,该方法看起来像这样的

      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实例来收集输出,等等......我甚至可以采用克隆和替换现有的方法文档中的节点。

      有什么想法或想法吗?

1 个答案:

答案 0 :(得分:0)

你应该在后端,即在PHP中执行此操作:

http://www.php.net/manual/en/function.strip-tags.php

此功能支持您可以使用的允许标签列表。