C#HtmlEncode – ISO-8859-1实体名称与数字

根据ISO-8859-1标准的下表 ,似乎存在与每个保留的HTML字符相关联的实体名称和实体编号。

例如,对于角色é

实体名称: é

实体编号: é

同样,对于角色>

实体名称: >

实体编号: >

对于给定的字符串, HttpUtility.HtmlEncode返回一个HTML编码的字符串,但我无法弄清楚它是如何工作的。 这就是我的意思:

 Console.WriteLine(HtmlEncode("é>")); //Outputs é> 

它似乎使用é字符的实体编号,但是>字符的实体名称。

那么HtmlEncode方法真的适用于ISO-8859-1标准吗? 如果是这样,有没有理由说它有时会使用实体名称而有时使用实体编号? 更重要的是,我可以强制它可靠地给我实体名称吗?

编辑:谢谢你的答案。 我执行搜索之前无法解码字符串。 在没有太多细节的情况下,文本存储在SharePoint列表中,“搜索​​”由SharePoint本身完成(使用CAML查询)。 所以基本上,我不能。

我试图想出一种将实体数字转换为名称的方法,.NET中是否有一个函数可以做到这一点? 还是其他任何想法?

这就是该方法的实现方式。 对于某些已知字符,它使用相应的实体,而对于其他所有字符,它使用相应的hex值,并且您无法修改此行为。 从System.Net.WebUtility.HtmlEncode的实现中摘录(如reflection器所示):

 ... if (ch <= '>') { switch (ch) { case '&': { output.Write("&"); continue; } case '\'': { output.Write("'"); continue; } case '"': { output.Write("""); continue; } case '<': { output.Write("<"); continue; } case '>': { output.Write(">"); continue; } } output.Write(ch); continue; } if ((ch >= '\x00a0') && (ch < 'Ā')) { output.Write("&#"); output.Write(((int) ch).ToString(NumberFormatInfo.InvariantInfo)); output.Write(';'); } ... 

这就是说你不应该关心,因为这种方法总能产生有效,安全和正确编码的HTML。

HtmlEncode遵循规范。 ISO标准为每个实体指定名称和编号,名称和编号是等效的。 因此, HtmlEncode的符合实现可以自由地将所有点编码为数字,或者全部作为名称或两者的某种混合编码。

我建议你从另一个方向解决你的问题:在目标文本上调用HtmlDecode ,然后使用原始字符串搜索解码的文本。

ISO-8859-1与HTML字符编码并不真正相关。 来自维基百科:

无论页面的编码如何,数字引用始终引用Unicode代码点。

仅对于未定义的Unicode代码点,经常使用ISO-8859-1:

除了换行符,制表符和回车符之外,禁止使用引用永久未定义字符和控制字符的数字引用。 也就是说,hex范围00-08,0B-0C,0E-1F,7F和80-9F中的字符不能用于HTML文档,甚至不能用于引用,因此例如“TM”不允许。 但是,为了向后兼容忽略此限制的早期HTML作者和浏览器,某些浏览器将80-9F范围内的原始字符和数字字符引用解释为表示映射到Windows-1252编码中字节80-9F的字符。

现在回答您的问题:为了使搜索工作最佳,您应该使用未编码的搜索字符串搜索未编码的HTML(首先剥离HTML标记)。 匹配编码字符串将导致意外结果,例如基于HTML标记或注释的命中,并且由于HTML中在文本中不可见的差异而丢失命中。

我做了这个function,我觉得它会有所帮助

  string BasHtmlEncode(string x) { StringBuilder sb = new StringBuilder(); foreach (char c in x.ToCharArray()) sb.Append(String.Format("&#{0};", Convert.ToInt16(c))); return(sb.ToString()); } 

我开发了以下代码来保持az,AZ和0-1不编码但是rest:

 public static string Encode(string source) { if (string.IsNullOrEmpty(source)) return string.Empty; var sb = new StringBuilder(source.Length); foreach (char c in source) { if (c >= 'a' && c <= 'z') { sb.Append(c); } else if (c >= 'A' && c <= 'Z') { sb.Append(c); } else if (c >= '0' && c <= '9') { sb.Append(c); } else { sb.AppendFormat("&#{0};",Convert.ToInt32(c)); } } return sb.ToString(); }