Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi TJson.Format und Umlaute (https://www.delphipraxis.net/201836-tjson-format-und-umlaute.html)

Codehunter 2. Sep 2019 08:33

TJson.Format und Umlaute
 
Hallo!

Mir ist aufgefallen, dass TJson.Format mit Umlauten nicht klar kommt. Wenn ich in einem Json-String z.B. das Wort "Straße" habe und mir den JsonValue mit .ToString ausgeben lasse, wird daraus völlig korrekt "Stra\u00dfe". Bei einem TJson.Format(MyJsonValue) wird daraus aber ein "Straße" als Unicode-String. Was dann natürlich bei mir im weiteren Verlauf beim Versenden via Indy zu serverseitigem Umlautesalat führt.

Übergangsweise sende ich jetzt erstmal unformatiertes JSON, damit scheints zu gehen. Aber wie bekomme ich ein korrekt UTF8-kodiertes und formatiertes JSON zusammen? Einfach ein UTF8Encode(TJson.Format(MyJsonValue)) machen?

Grüße
Cody

Schokohase 2. Sep 2019 09:03

AW: TJson.Format und Umlaute
 
Da ein JSON-String in UTF8 kodiert wird dürfen nur UTF8-Zeichen verwendet werden.
Zitat:

A string is a sequence of zero or more Unicode characters, wrapped in double quotes, using backslash escapes. A character is represented as a single character string. A string is very much like a C or Java string.
(Quelle: https://json.org)

Hier die komplette Liste mit allen UTF8 Zeichen.
https://www.fileformat.info/info/charset/UTF-8/list.htm

Wie du siehst ist da auch das ß dabei, also ist da erst einmal alles korrekt.

Codehunter 2. Sep 2019 09:30

AW: TJson.Format und Umlaute
 
Nein ist nicht korrekt. Ich red auch nicht von der Json-Spezifikation sondern davon was Delphi da veranstaltet. TJson.Format gibt eben keinen String mit escaped Unicode-Chars zurück sondern einen Delphi-Unicode-String unescaped.

Schokohase 2. Sep 2019 09:42

AW: TJson.Format und Umlaute
 
Also wenn wir davon reden, was Delphi da mittels
Delphi-Quellcode:
TJson
veranstaltet, dann müssen wir auch über die JSON-Spezifikation sprechen, denn das war die Grundlage für die Funktionsweise von
Delphi-Quellcode:
TJson
.

Das Delphi einen "normalen"
Delphi-Quellcode:
string
als Ergebnis zurückliefert, ja das sollte klar sein. Allerdings sollten sich nach dem
Delphi-Quellcode:
TJson.Format
nur noch Zeichen befinden, die sich auch in der UTF8-Zeichentabelle befinden.

Und warum sollte da etwas escaped werden, wenn es nicht escaped werden muss (das Zeichen ist in der UTF8-Zeichentabelle enthalten).

Ansonsten, welche Zeichen sollen denn alle escaped werden? Alle? Einige? Nach welchen Kriterien?

Aber eventuell hilft dir auch noch die Beschreibung aus der RFC
Zitat:

Code:
2.5. Strings

   The representation of strings is similar to conventions used in the C
   family of programming languages. A string begins and ends with
   quotation marks. All Unicode characters may be placed within the
   quotation marks except for the characters that must be escaped:
   quotation mark, reverse solidus, and the control characters (U+0000
   through U+001F).

   Any character may be escaped. If the character is in the Basic
   Multilingual Plane (U+0000 through U+FFFF), then it may be
   represented as a six-character sequence: a reverse solidus, followed
   by the lowercase letter u, followed by four hexadecimal digits that
   encode the character's code point. The hexadecimal letters A though
   F can be upper or lowercase. So, for example, a string containing
   only a single reverse solidus character may be represented as
   "\u005C".

   Alternatively, there are two-character sequence escape
   representations of some popular characters. So, for example, a
   string containing only a single reverse solidus character may be
   represented more compactly as "\\".

   To escape an extended character that is not in the Basic Multilingual
   Plane, the character is represented as a twelve-character sequence,
   encoding the UTF-16 surrogate pair. So, for example, a string
   containing only the G clef character (U+1D11E) may be represented as
   "\uD834\uDD1E".

(Quelle: https://www.ietf.org/rfc/rfc4627.txt)
Daraus geht hervor, was escaped werden muss, und was escaped werden darf.

PS

Mich dünkt du hast ein anderes Problem und versuchst dieses nun dem JSON in die Schuhe zu schieben.

Codehunter 2. Sep 2019 10:04

AW: TJson.Format und Umlaute
 
Siehe Eingangspost. TJsonValue.ToString und TJson.Format verhalten sich unterschiedlich. Da ich anwenderseitig eine Umschaltmöglichkeit zwischen formatiert und unformatiert habe, brauche ich eine Vereinheitlichung was den Umgang mit Umlauten angeht.

Der schöne Günther 2. Sep 2019 11:26

AW: TJson.Format und Umlaute
 
Nur nochmal das Ergebnis:

Delphi-Quellcode:
procedure p();
var
   jsonObject: TJSONObject;
begin
   jsonObject := TJsonObject.Create();
   jsonObject.AddPair('text', 'Straße');

   Writeln( jsonObject.ToString() );
   Writeln( jsonObject.ToJSON() );
   WriteLn( Rest.Json.TJson.Format(jsonObject) );
end;
ergibt

Code:
{"text":"Straße"}
{"text":"Stra\u00DFe"}
{
  "text":"Straße"
}

Schokohase 2. Sep 2019 11:41

AW: TJson.Format und Umlaute
 
Zur Ausgangsfrage zurück:
Zitat:

Zitat von Codehunter (Beitrag 1444330)
Aber wie bekomme ich ein korrekt UTF8-kodiertes und formatiertes JSON zusammen?

ganz einfach mit
Delphi-Quellcode:

procedure p();
var
   jsonObject: TJSONObject;
begin
   jsonObject := TJsonObject.Create();
   jsonObject.AddPair('text', 'Straße');

   Writeln( jsonObject.ToString() ); // unformatiert
   WriteLn( Rest.Json.TJson.Format(jsonObject) ); // formatiert
end;
ergibt
Code:
{"text":"Straße"}
{
  "text":"Straße"
}
Um davon jetzt eine UTF8 kodierte Bytefolge zu erhalten nimmt man z.B.
Delphi-Quellcode:
TEncoding.UTF8.GetBytes( json );
.
Wenn man etwas mit Indy verschicken will, dann reicht es in der Regel den String zu verwenden und die entsprechend gewünschte Kodierung anzugeben. Das Umwandeln von dem String in die Kodierung übernehmen dann eigentlich die Indy-Komponenten.

Nur so nebenbei erwähnt:

Das Ergebnis
Code:
{"text":"Stra\u00DFe"}
wird ja auch in einem Delphi-Unicode zurückgegeben. Ist also auch nicht UTF8 oder was auch immer vermutet.

Uwe Raabe 2. Sep 2019 13:10

AW: TJson.Format und Umlaute
 
Der Unterschied sind die intern verwendeten Methoden. Während ToString und Format auf ToChars zurückgreifen, macht ToJSON Gebrauch von ToBytes. Bei einem TJSONString ist ToBytes aber so implementiert, daß es alle Zeichen > #128 (und auch ein paar < #32) als /u escaped darstellt. Das ToChars beschränkt sich da lediglich auf ein paar spezielle Zeichen.

Codehunter 2. Sep 2019 13:36

AW: TJson.Format und Umlaute
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1444364)
Der Unterschied sind die intern verwendeten Methoden. Während ToString und Format auf ToChars zurückgreifen, macht ToJSON Gebrauch von ToBytes. Bei einem TJSONString ist ToBytes aber so implementiert, daß es alle Zeichen > #128 (und auch ein paar < #32) als /u escaped darstellt. Das ToChars beschränkt sich da lediglich auf ein paar spezielle Zeichen.

Jepp so seh ich das auch. Nur unglücklicherweise mag der Server keine unmaskierten Umlaute und (warum auch immer) kein unformatiertes Json. Heißt, ich muss meinen Request dem nicht standardkonformen Server bekömmlich vorverdauen. Also mit Zeilenumbrüchen, Indentations und \u-escaped Umlaute.

Uwe Raabe 2. Sep 2019 13:59

AW: TJson.Format und Umlaute
 
Zitat:

Zitat von Codehunter (Beitrag 1444369)
Nur unglücklicherweise mag der Server keine unmaskierten Umlaute und (warum auch immer) kein unformatiertes Json.

Das ist allerdings schon recht ungewöhnlich, was eine fertige Implementierung für diesen Fall doch eher unwahrscheinlich macht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:36 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz