Есть ли стандартная функция Delphi для экранирования HTML?
У меня есть отчет, который должен взять управление сеткой и произвести вывод HTML. Один из столбцов в сетке может отображать любое из нескольких значений или <Any>
. Когда это выводится в HTML, конечно, оно заканчивается пустым.
Возможно, я мог бы написать некоторую рутину, чтобы использовать StringReplace, чтобы превратить ее в <Any>
, чтобы она отображала этот конкретный случай правильно, но я полагаю, что, вероятно, в RTL есть что-то, что уже было проверено, и делает это правильно. Кто-нибудь знает, где я могу его найти?
Ответы
Ответ 1
Я на 99% уверен, что такой функции не существует в RTL (как в Delphi 2009). Конечно, однако - тривиально написать такую функцию.
Обновление
HTTPUtil.HTMLEscape - это то, что вы ищете:
function HTMLEscape(const Str: string): string;
Я не смею публиковать здесь код (возможно, нарушение авторских прав), но процедура очень проста. Он кодирует "<", " > ", "&" и "" до <
, >
, &
и "
, а также заменяет символы # 92, # 160.. # 255 до десятичных кодов, например \
.
Этот последний шаг не нужен, если файл UTF-8, а также нелогичен, потому что более высокие специальные символы, такие как ∮, остаются такими, какими они есть, тогда как кодируются более низкие специальные символы, такие как ×.
Обновление 2
В ответ на ответ Stijn Sanders я сделал простой тест производительности.
program Project1;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils;
var
t1, t2, t3, t4: Int64;
i: Integer;
str: string;
const
N = 100000;
function HTMLEncode(const Data: string): string;
var
i: Integer;
begin
result := '';
for i := 1 to length(Data) do
case Data[i] of
'<': result := result + '<';
'>': result := result + '>';
'&': result := result + '&';
'"': result := result + '"';
else
result := result + Data[i];
end;
end;
function HTMLEncode2(Data: string):string;
begin
Result:=
StringReplace(
StringReplace(
StringReplace(
StringReplace(
Data,
'&','&',[rfReplaceAll]),
'<','<',[rfReplaceAll]),
'>','>',[rfReplaceAll]),
'"','"',[rfReplaceAll]);
end;
begin
QueryPerformanceCounter(t1);
for i := 0 to N - 1 do
str := HTMLEncode('Testing. Is 3*4<3+4? Do you like "A & B"');
QueryPerformanceCounter(t2);
QueryPerformanceCounter(t3);
for i := 0 to N - 1 do
str := HTMLEncode2('Testing. Is 3*4<3+4? Do you like "A & B"');
QueryPerformanceCounter(t4);
Writeln(IntToStr(t2-t1));
Writeln(IntToStr(t4-t3));
Readln;
end.
Выходной сигнал
532031
801969
Ответ 2
Кажется, здесь небольшой конкурс:) Вот еще одна реализация:
function HTMLEncode3(const Data: string): string;
var
iPos, i: Integer;
procedure Encode(const AStr: String);
begin
Move(AStr[1], result[iPos], Length(AStr) * SizeOf(Char));
Inc(iPos, Length(AStr));
end;
begin
SetLength(result, Length(Data) * 6);
iPos := 1;
for i := 1 to length(Data) do
case Data[i] of
'<': Encode('<');
'>': Encode('>');
'&': Encode('&');
'"': Encode('"');
else
result[iPos] := Data[i];
Inc(iPos);
end;
SetLength(result, iPos - 1);
end;
Обновление 1: Обновлен изначально предоставлен неверный код.
Обновление 2: И время:
HTMLEncode : 2286508597
HTMLEncode2: 3577001647
HTMLEncode3: 361039770
Ответ 3
Я обычно использую этот код:
function HTMLEncode(Data:string):string;
begin
Result:=
StringReplace(
StringReplace(
StringReplace(
StringReplace(
StringReplace(
Data,
'&','&',[rfReplaceAll]),
'<','<',[rfReplaceAll]),
'>','>',[rfReplaceAll]),
'"','"',[rfReplaceAll]),
#13#10,'<br />'#13#10,[rfReplaceAll]);
end;
(авторское право с открытым исходным кодом)
Ответ 4
У блока HTTPApp есть функция, называемая HTMLEncode. Он также имеет другие связанные с HTML/HTTP функции.
Ответ 5
как насчет этого способа замены специальных символов:
function HtmlWeg(sS: String): String;
var
ix,cc: Integer;
sC, sR: String;
begin
result := sS;
ix := pos('\u00',sS);
while ix >0 do
begin
sc := copy(sS,ix+4,2) ;
cc := StrtoIntdef('$' +sC,32);
sR := '' + chr(cc);
sS := Stringreplace(sS, '\u00'+sC,sR,[rfreplaceall]) ;
ix := pos('\u00',sS);
end;
result := sS;
end;
Ответ 6
Моя функция объединяет for-loop с минимальным перераспределением строки:
function HtmlEncode(const Value: string): string;
var
i: Integer;
begin
Result := Value;
i := 1;
while i <= Length(Result) do
begin
if Result[i] = '<' then
begin
Result[i] := '&';
Insert('lt;', Result, i + 1);
Inc(i, 4);
end
else if Result[i] = '>' then
begin
Result[i] := '&';
Insert('gt;', Result, i + 1);
Inc(i, 4);
end
else if Result[i] = '"' then
begin
Result[i] := '&';
Insert('quot;', Result, i + 1);
Inc(i, 6);
end
else if Result[i] = '&' then
begin
Insert('amp;', Result, i + 1);
Inc(i, 5);
end
else
Inc(i);
end;
end;
Ответ 7
Я не знаю, в какую версию delphi она была введена, но есть блок System.NetEncoding
, который имеет:
TNetEncoding.HTML.Encode
TNetEncoding.HTML.Decode
функции. Прочитайте здесь. Вам больше не нужны внешние библиотеки.