Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TJSONValue und Dezimalzahlen (https://www.delphipraxis.net/197048-tjsonvalue-und-dezimalzahlen.html)

Codehunter 13. Jul 2018 16:12

Delphi-Version: 10.2 Tokyo

TJSONValue und Dezimalzahlen
 
Hallo!

Ich habe einen JSON-String mit einer Dezimalzahl, die ich in ihrer String-Representation auslesen will. Dummerweise passiert da eine Typumwandlung auf Ebene der Systemeinstellungen:
Code:
{
  "key":123.4
}
Ergibt bei
Delphi-Quellcode:
(TJSONValue as TJSONString).Value
eine ungültige Typumwandlung und bei
Delphi-Quellcode:
(TJSONValue as TJSONNumber).ToString
den Wert "123,40"

Ich möchte aber die Originalschreibweise, so wie im JSON notiert, also "123.4".

Vielleicht ist die Woche schon zu alt, der Freitag zu lang, wie auch immer, ich steh auf dem Schlauch :-(

Grüße
Cody

Der schöne Günther 13. Jul 2018 16:40

AW: TJSONValue und Dezimalzahlen
 
Zitat:

Zitat von Codehunter (Beitrag 1407226)
und bei
Delphi-Quellcode:
(TJSONValue as TJSONNumber).ToString
den Wert "123,40"

Also bei mir kommt 1:1 raus was im Json steht. Delphi 10 Seattle.
Delphi-Quellcode:
procedure p();
const
   input = '{"key":123.4}';
var
   jsonObject: TJSONObject;
   jsonNumber: TJSONNumber;
begin
   jsonObject := TJsonObject.ParseJSONValue(input) as TJSONObject;
   jsonNumber := jsonObject.Values['key'] as TJSONNumber;
   WriteLn( jsonNumber.ToString() ); // Ergibt "123.4"
end;
Beinhaltet dein "Originalschreibweise" auch dass eine "123.4000" nicht als "123.4" ausgegeben werden darf?

Codehunter 13. Jul 2018 17:42

AW: TJSONValue und Dezimalzahlen
 
Ja das dachte ich auch. Aber scheinbar spielen da auch Regionaleinstellungen mit rein. Worauf ich hinaus will ist sozusagen eine Raw-String-Representation des Wertes. Im Grunde bräuchte ich etwas das gar nicht erst eine Typumwandlung macht.

Codehunter 16. Jul 2018 07:28

AW: TJSONValue und Dezimalzahlen
 
Nachtrag:
Zitat:

Zitat von Der schöne Günther (Beitrag 1407232)
Beinhaltet dein "Originalschreibweise" auch dass eine "123.4000" nicht als "123.4" ausgegeben werden darf?

Ja, ganz genau so! Wenns als "123.4000" notiert ist, brauche ich einen String der "123.4000" enthält.

Uwe Raabe 16. Jul 2018 09:03

AW: TJSONValue und Dezimalzahlen
 
Zeig doch mal etwas mehr Code. Mit dem obigen Beispiel bekomme ich hier ebenfalls den korrekten String raus, obwohl der DecimalSeparator ein Komma ist. Ich vermute, daß die Umwandlung an einer anderen Stelle passiert.

Codehunter 16. Jul 2018 09:23

AW: TJSONValue und Dezimalzahlen
 
Du hast völlig recht Uwe. Der Fehler war, dass ich TJSONValue vor dem .ToString zu einer TJSONNumber gecastet habe.

Der schöne Günther 16. Jul 2018 09:24

AW: TJSONValue und Dezimalzahlen
 
So ungefähr?

Delphi-Quellcode:
type
   TJsonObjectHelper = class helper for System.JSON.TJSONObject
      function FindPair(const PairName: String): TJSONPair;
   end;

procedure p();
const
   input = '{"key": 123.400}';
var
   jsonObject: TJSONObject;
   jsonPair: TJSONPair;
begin
   jsonObject := TJsonObject.ParseJSONValue(input) as TJSONObject;
   try
      jsonPair := jsonObject.FindPair('key');
      WriteLn( jsonPair.JsonValue.ToString() ); // Ergibt "123.400"
   finally
      jsonObject.Destroy();
   end;
end;

{ TJsonObjectHelper }

function TJsonObjectHelper.FindPair(const PairName: String): TJSONPair;
var
  Candidate: TJSONPair;
  I: Integer;
begin
  for I := 0 to Count - 1 do
  begin
   Candidate := TJSONPair(self.FMembers[I]);
   if (Candidate.JsonString.Value = PairName) then
   begin
     Exit(Candidate);
   end;
  end;
  Result := nil;
end;

himitsu 16. Jul 2018 09:30

AW: TJSONValue und Dezimalzahlen
 
Warum liest du das dann nicht einfach als Zahl (Float) aus und konvertierst selber?

Ansonsten geht es halt über die globalen FormatStettings.
Lösung: Stell dein Windows auf englisch um und schon hast du deine 123.4 :stupid:

Codehunter 17. Jul 2018 07:05

AW: TJSONValue und Dezimalzahlen
 
Zitat:

Zitat von himitsu (Beitrag 1407378)
Warum liest du das dann nicht einfach als Zahl (Float) aus und konvertierst selber?

Dass die Anforderung überhaupt besteht ergibt sich aus der verqueren Schnittstellenspezifikation. Mehrere Felder haben kontextabhängig unterschiedliche Anzahl Dezimalstellen und bei Antworten bestehen sie auch auf ebensolche, selbst wenn 123.000000 zurückgegeben werden muss. FormatSettings kann ich also nicht hardcoded verwenden :-(

himitsu 17. Jul 2018 09:44

AW: TJSONValue und Dezimalzahlen
 
Wenn, dann müssen sie die Zahlen eben als String speichern und nicht als Float.
Alles andere wiederspricht grob fahrlässig der Spezifikation des JSON.

Wenn der Nummeric-Typ den Wert nunmal auch Nummerisch speichert, dann gehen beim Einlesen automatisch sämtliche Informationen über führende/folgende Nullen verloren.
Kein "ordentlicher" JSON-Parser/Konverter wird sowas ohne Informationsverlust einlesen und schon garnicht speichern können.
Fazit: Du mußt den ganzen JSON-String selbst parsen und behandeln.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:56 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