![]() |
lkJSON UTF-8 Problem üöä
Hallo,
ich habe das Problem, dass ich mit Delphi 2010 und Indy etwas heruntergeladen habe über idhttp.get. Der Inhalt ist laut Server-Betreiber UTF-8 codiert, also habe ich folgendes verwendet:
Delphi-Quellcode:
Das Download-Ergebnis ist korrekt und komplett Menschenlesbar, d.h. wenn ich das Result in einem Memo anzeigen lasse, werden üöä richtig dargestellt.
ssResult := TStringStream.Create('', TEncoding.UTF8);
idhttp.Get(_URL, ssResult); Diesen String muss ich nun auch auswerten, da es sich hierbei um ein JSON handelt. Ich verwendet lkJSON mit Delphi 2010. Zur Fehlersuche habe ich den problematischen String hier in die Konstante gespeichert.
Delphi-Quellcode:
Innerhalb von lkJSON entsteht das Problem an dieser Stelle:
procedure TForm2.Button3Click(Sender: TObject);
var i: integer; t: string; u: UTF8String; JSON_Document: TlkJSONbase; JSON_Element: TlkJSONbase; title: TlkJSONbase; const JSONTEXT = '[{"id":270513903,"title":"Blättern"}]'; begin u := UTF8Encode(JSONTEXT); JSON_Document := TlkJSON.ParseText(u); // bis hier ist in Variable u "Blättern" noch korrekt in der "Liste der überwachten Ausdrücke" zu sehen for i := 0 to JSON_Document.Count - 1 do begin JSON_Element := JSON_Document.Child[i]; if assigned(JSON_Element) then begin title := JSON_Element.Field['title']; if assigned(title) then begin u := title.Value; // u und title.Value halten nun 'Bl�ttern' bzw. 'Bl?ttern' #3F74 t := UTF8Decode(u); // bringt nix if copy(t, 3, 1) <> 'ä' then begin // FEHLER sleep(0); // für BreakPoint end; end; end; end; end;
Delphi-Quellcode:
Hier wird aus dem lesbaren Text der Datenmüll.
js := TlkJSONstring.Create;
{$ifdef USE_D2009} js.FValue := UTF8ToString(ws); // auch bei meinem Delphi 2010 wird diese Zeile verwendet {$else} js.FValue := UTF8Decode(ws); {$endif} EDIT: Wenn ich nun in dem o.g. Beispiel
Delphi-Quellcode:
durch
t := UTF8Decode(u); // bringt nix
Delphi-Quellcode:
funktioniert es korrekt, also machen beide Funktionen gerade das Gegenteil von dem, was der Name sagt, bzw. ich von Ihnen erwarte?
t := UTF8ENCODE(u);
"u" ist ja UTF8 codiert. "t" ist nicht UTF8 codiert und bietet auch als Variable nur ein Byte pro Zeichen (?) Jetzt speichere ich in "t" etwas rein was die Variable speichermäßig gar nicht aufnehmen kann, und kodiere einen UTF8-String erneut zu UTF8 damit es auch wirklich klappt? Ich bin verwirrt. Ok, jetzt mal ernsthaft: Wahrscheinlich sind in Delphi 2010 eh alle "string"-Variablen längt Multibyte, können also von Haus aus UTF8 speichern, und der Datentyp "UTF8String" ist veraltet oder wird nur für explizite Sonderfälle benötigt. JSON hat wohl die Sonderzeichen zwar im MultiByte-Format zurückgegeben, aber die "Markierung" DASS es MultiByte oder was-auch-immer ist hat wohl gefehlt, so dass die UTF8-Bytes #3F74 als 2 Bytes eines Nicht-MultiByte-Strings interpretiert wurden. Warum!? Durch das erneute Encodieren als UTF8 wurde diese "Markierung" wieder hergestellt und Delphi ist flexibel genug, um die Sonderzeichen auch dann korrekt in einem "normalen" string darzustellen, wenn dieser nicht Explizit von UTF8 nach ANSI oder UNICODE zurückgewandelt wurde. Das eigentliche Problem ist also schon vor dem Absenden dieses Posts gelöst, aber vielleicht helfen ja meine Gedankengänge jemandem mit dem selben Problem weiter (Speziell: Indy + JSON + UFT8 --> TStringStream.Create('', TEncoding.UTF8) !!), und vielleicht kann mir jemand noch 1-2 Sätze dazu sagen, weshalb das mit UTF8Decode/UTF8Encode für mich aktuell nicht ganz nachvollziehbar ist... Danke, lg! |
AW: lkJSON UTF-8 Problem üöä
Schaut so aus, als ob die Person, die diese Unit für Delphi 2009 und höher portiert hat, keine Ahnung hatte (siehe auch die vielen Warnings, die der Compiler für die Unit wirft - ich hab grad v1.07 gezogen). Für mich sieht das so aus, als ob er annimmt, dass ein UTF8 String als UnicodeString gespeichert wird (also für ein ü 2 Unicode Zeichen verbraucht werden - analog wie es vor Delphi 2009 in einem UTF8 kodierten AnsiString der Fall war (siehe Warning W1058 an von dir bereits genannten Stelle - Zeile 1883).
Im übrigen nimmt die ParseText Methode schon den falschen Datentyp entgegen - wurde vermutlich auch nicht bei der Umstellung berücksichtigt (siehe W1057 in der entsprechenden Stelle - Delphi führt dort eine automatische UTF8->UnicodeString konvertierung durch) Und nein, UTF8String ist nicht veraltet ... |
AW: lkJSON UTF-8 Problem üöä
Danke Stevie für die Antwort.
Ok, also dann doch ein Fehler von den JSON Komponenten. Ich nehme an, wer von Euch mit JSON arbeitet hat eine neuere Version von Delphi, wo JSON ab Werk mitgeliefert mit? Gibt es alternativ eine (kommerzielle) JSON Komponente die Delphi 2010 kompatibel ist und eine wenig höhere "Qualität" hat? [Ich will auf keinen Fall undankbar sein, lkJSON ist ansonsten echt Klasse...] |
AW: lkJSON UTF-8 Problem üöä
|
AW: lkJSON UTF-8 Problem üöä
Oder
![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:57 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz