C# HtmlEncode - ISO-8859-1 имена объектов против номеров
В соответствии со следующей таблицей для стандарта ISO-8859-1, похоже, что имя объекта и номер объекта связаны с каждым зарезервированным символом HTML.
Так, например, для персонажа é
:
Имя сущности: é
Номер объекта: é
Аналогично для персонажа >
:
Имя сущности: >
Номер объекта: >
Для данной строки HttpUtility.HtmlEncode
возвращает строку в кодировке HTML, но я не могу понять, как это работает. Вот что я имею в виду:
Console.WriteLine(HtmlEncode("é>"));
//Outputs é>
Кажется, он использует номер объекта для é
символ, но имя объекта для >
персонаж.
Так действительно ли метод HtmlEncode работает со стандартом ISO-8859-1? Если это так, есть ли причина, по которой он иногда использует имя объекта, а иногда - номер объекта? Что еще более важно, могу ли я заставить его надежно назвать имя сущности?
РЕДАКТИРОВАТЬ: Спасибо за ответы, ребята. Я не могу декодировать строку, прежде чем выполнить поиск, хотя. Не вдаваясь в подробности, текст сохраняется в списке SharePoint, а "поиск" выполняется самой SharePoint (с использованием запроса CAML). В общем, я не могу.
Я пытаюсь придумать способ преобразования номеров сущностей в имена. Есть ли в.NET функция, которая это делает? Или любая другая идея?
5 ответов
Вот как метод был реализован. Для некоторых известных символов он использует соответствующую сущность, а для всего остального он использует соответствующее шестнадцатеричное значение, и вы мало что можете сделать, чтобы изменить это поведение. Выдержка из реализации System.Net.WebUtility.HtmlEncode
(как видно с отражателем):
...
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.
Я сделал эту функцию, я думаю, что это поможет
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());
}
HtmlEncode
следует за спецификацией. Стандарт ISO определяет как имя, так и номер для каждого объекта, а имя и номер эквивалентны. Следовательно, соответствующая реализация HtmlEncode
свободно кодировать все точки как числа, или все как имена, или некоторую смесь двух.
Я предлагаю вам подойти к вашей проблеме с другой стороны: позвоните HtmlDecode
на целевом тексте, затем ищите декодированный текст, используя необработанную строку.
ISO-8859-1 не имеет никакого отношения к кодированию символов HTML. Из Википедии:
Числовые ссылки всегда ссылаются на кодовые точки Unicode, независимо от кодировки страницы.
Только для неопределенных кодовых точек Unicode часто используется ISO-8859-1:
Использование числовых ссылок, которые ссылаются на постоянно неопределенные символы и управляющие символы, запрещено, за исключением символов перевода строки, табуляции и возврата каретки. То есть символы в шестнадцатеричных диапазонах 00–08, 0B–0C, 0E–1F, 7F и 80–9F нельзя использовать в документе HTML, даже по ссылке, поэтому, например, "™" не допускается, Однако для обратной совместимости с ранними авторами HTML и браузерами, которые игнорировали это ограничение, необработанные символы и ссылки на числовые символы в диапазоне 80–9F интерпретируются некоторыми браузерами как представляющие символы, сопоставленные с байтами 80–9F в кодировке Windows-1252.
Теперь, чтобы ответить на ваш вопрос: чтобы поиск работал лучше, вы должны действительно искать незашифрованный HTML (сначала удаляя теги HTML), используя незашифрованную строку поиска. Сопоставление закодированных строк приведет к неожиданным результатам, таким как совпадения на основе тегов или комментариев HTML, а также совпадения, отсутствующие из-за различий в HTML, которые невидимы в тексте.
Я разработал следующий код, чтобы аз,AZ и 0-1 не кодировались, а оставались:
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();
}