2010-06-03 4 views
23

Ich habe einen Bericht, der eine Rastersteuerung übernehmen und HTML-Ausgabe erzeugen soll. Eine der Spalten im Raster kann eine beliebige Anzahl von Werten anzeigen, oder <Any>. Wenn dies in HTML ausgegeben wird, endet es natürlich leer.Gibt es eine Delphi-Standardfunktion für das Entweichen von HTML?

Ich könnte wahrscheinlich eine Routine schreiben, um StringReplace zu verwenden, um das in &lt;Any&gt; zu verwandeln, so würde es diesen bestimmten Fall richtig anzeigen, aber ich denke, es gibt wahrscheinlich eine in der RTL irgendwo, die bereits getestet wurde und es richtig macht. Wer weiß, wo ich es finden könnte?

+1

Ein Delphi Weg, HTML zu entkommen ... Intraweb! ;-) – LachlanG

Antwort

16

Ich bin zu 99% sicher, dass eine solche Funktion in der RTL nicht existiert (ab Delphi 2009). Natürlich ist es jedoch trivial, eine solche Funktion zu schreiben.

aktualisieren

HTTPUtil.HTMLEscape ist das, was Sie suchen:

function HTMLEscape(const Str: string): string; 

ich es nicht wagen, den Code hier (Urheberrechtsverletzung, wahrscheinlich), aber die Routine zu veröffentlichen ist sehr einfach. Es kodiert "<", ">", "&" und ""“zu &lt;, &gt;, &amp; und &quot;. Es ersetzt auch Zeichen 92 #, # 160 .. # 255 Codes auf dezimal, zB &#92;.

Dieser letzte Schritt ist nicht erforderlich, wenn die Datei UTF-8, und auch unlogisch ist, weil höhere Sonderzeichen, wie ∮ gelassen werden wie sie sind, während niedrigere Sonderzeichen, wie ×, codiert werden.

Update 2

Als Antwort auf die Antwort von Stijn Sanders machte ich einen einfachen Leistungstest.

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 + '&lt;'; 
     '>': result := result + '&gt;'; 
     '&': result := result + '&amp;'; 
     '"': result := result + '&quot;'; 
    else 
     result := result + Data[i]; 
    end; 

end; 

function HTMLEncode2(Data: string):string; 
begin 
    Result:= 
    StringReplace(
    StringReplace(
    StringReplace(
    StringReplace(
     Data, 
     '&','&amp;',[rfReplaceAll]), 
     '<','&lt;',[rfReplaceAll]), 
     '>','&gt;',[rfReplaceAll]), 
     '"','&quot;',[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. 

Der Ausgang ist

532031 
801969 
2

ich in der Regel nur diesen Code verwenden:

function HTMLEncode(Data:string):string; 
begin 
    Result:= 
    StringReplace(
    StringReplace(
    StringReplace(
    StringReplace(
    StringReplace(
     Data, 
     '&','&amp;',[rfReplaceAll]), 
     '<','&lt;',[rfReplaceAll]), 
     '>','&gt;',[rfReplaceAll]), 
     '"','&quot;',[rfReplaceAll]), 
     #13#10,'<br />'#13#10,[rfReplaceAll]); 
end; 

(? Copyright es open source)

+0

Das sieht * viel * langsamer aus als eine einfache Schleife: für i: = 1 bis Länge (Daten) do case ord (Daten [i]) von ... –

+0

habe ich gerade getestet: Nested StringReplace: 801259 ticks. Eine einzelne Schleife: 532037 Ticks. –

+0

Aber natürlich scheitert der * sehr einfache * Looping-Ansatz mit # 13 # 10 ... –

12

Es scheint hier ein kleiner Wettbewerb ist :) Hier ist eine weitere Implementierung:

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('&lt;'); 
     '>': Encode('&gt;'); 
     '&': Encode('&amp;'); 
     '"': Encode('&quot;'); 
    else 
     result[iPos] := Data[i]; 
     Inc(iPos); 
    end; 
    SetLength(result, iPos - 1); 
end; 

Update 1: Aktualisiert ursprünglich bereitgestellten falschen Code.

Update 2: Und die Zeiten:

HTMLEncode : 2286508597 
HTMLEncode2: 3577001647 
HTMLEncode3: 361039770 
+0

Das ist eine sehr schöne Lösung! (Vielleicht ein bisschen Overkill, aber! :)) Der Hauptgewinn ist wahrscheinlich nicht die Move, aber die Tatsache, dass Sie nicht ständig mehr Platz für das Ergebnis zuweisen müssen. Ich würde Ihnen ein +1 geben, außer es wäre für die Tatsache, dass es keine Antwort auf die eigentliche Frage ist! :) –

+0

Nun, ich gebe dir +1, nur weil es ein schönes Beispiel für Optimierung ist. –

+0

(Übrigens: Sie wissen, dass es einen subtilen Unterschied zwischen einem "Inhalt" und einem "Wettbewerb" gibt? :)) –

2

Einheit HTTPApp hat eine Funktion Htmlencode genannt. Es hat auch andere HTML/HTTP-bezogene Funktionen.

+0

Wie schon lange vorher erwähnt ... –

+0

HTTPApp.HTMLEncode nicht korrekt eine Zeichenfolge in Delphi 2009 und 2010 - http://qc.embarcadero.com /wc/qcmain.aspx?d=78903 – mjn

0

wie über diese Art und Weise zu ersetzen Sonderzeichen:

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; 
+0

Die Standardfunktion wird speziell in dieser Frage gestellt, sodass Ihre Antwort nicht beantwortet wird, unabhängig davon, ob sie korrekt ist oder nicht. – lukelazarovic

0

kombiniert Meine Funktion die for-Schleife mit einer minimalen Neuzuteilung der Zeichenfolge:

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; 
0

Ich weiß nicht, in welcher delphi Version es eingeführt wurde, jedoch gibt es die System.NetEncoding Einheit, die aufweist:

TNetEncoding.HTML.Encode 
TNetEncoding.HTML.Decode 

f Verbindungen. Lesen Sie here. Sie brauchen dafür keine externen Bibliotheken mehr.

Verwandte Themen