![]() |
Json Array of String: Wie Array-Items per Schleife auslesen
Hallo,
mir fällt der Umgang mit Json noch ziemlich schwer. Ich habe 1 String-Array in der Json-Datei. Folgendes Json (gekürzt).
Code:
Ich habe den Json-Dateiinhalt in einem Json-Objekt:
{
"Database": { "DB-ServerName": "", "DB-Name": "", "DB-User": "", "DB-User-Pw": 0, "DB-Provider": 0 }, "ShorthandSymbol": [ "UxRT", "KuZT", "KpZR", "BFRS", "HKJD", "UDTR", "SI", "dgws", "DEFdg", "EIZ", "ITFd" ] }
Delphi-Quellcode:
Jetzt muss ich irgendwie über eine Schleife (?) die einzelnen Stringwerte aus dem Array auslesen.
...
VAR my_jsonObj: TJSONObject; BEGIN IF FileExists( ExtractFilePath( ParamStr( 0 ) ) + 'Settings.json' ) THEN BEGIN my_jsonObj := TJSONObject.ParseJSONValue( TFile.ReadAllText( ExtractFilePath( ParamStr( 0 ) ) + 'Settings.json' ) ) AS TJSONObject; ... Wie komme ich an die einzelnen Json-String-Array-Werte? Vielen Dank schon mal vorab. |
AW: Json Array of String: Wie Array-Items per Schleife auslesen
Mit
Delphi-Quellcode:
kommst du schon mal an das Array. Dort kannst du dann einfach über den Index auf die einzelnen Elemente zugreifen.
my_jsonObj.Values['ShorthandSymbol'] as TJSONArray
|
AW: Json Array of String: Wie Array-Items per Schleife auslesen
Vielen Dank, Uwe! :thumb:
Ich habe jetzt folgende Art einer Lösung:
Delphi-Quellcode:
Das Ganze scheint zu funktionieren, aber irgendwie fühlt sich das für mich noch nicht richtig an.
ShowMessage( ( ( my_jsonObj.Values['ShorthandSymbol'] AS TJSONArray ).Items[1] ).ToString );
|
AW: Json Array of String: Wie Array-Items per Schleife auslesen
Zitat:
![]()
Delphi-Quellcode:
Im Beispiel ist das nicht der Fall, es muss ein Custom-Serializer registriert werden:
uses
mormot.core.base, mormot.core.text, mormot.core.json, mormot.core.os; type TDBSettings = packed record DataBase: record DBServerName: String; // statt "DB-ServerName" DBName: String; DBUser: String; DBUserPw: Integer; DBProvider: Integer; end; ShorthandSymbol: TStringDynArray; // array of String function LoadFromFile(const pmcFileName: TFileName): Boolean; procedure SaveToFile(const pmcFileName: TFileName); end; function TDBSettings.LoadFromFile(const pmcFileName: TFileName): Boolean; begin Result := RecordLoadJson(Self, StringFromFile(pmcFileName), TypeInfo(TDBSettings)); end; procedure TDBSettings.SaveToFile(const pmcFileName: TFileName); begin FileFromString(RecordSaveJson(Self, TypeInfo(TDBSettings)), pmcFileName); end;
Delphi-Quellcode:
Und so anwenden:
uses
mormot.core.base, mormot.core.data, mormot.core.text, mormot.core.json, mormot.core.rtti, mormot.core.os; type TDBSettingDataBase = class(TObject) private FDBServerName: String; FDBName: String; FDBUser: String; FDBUserPw: Integer; FDBProvider: Integer; protected class procedure ReadDataBaseJson(var pmvContext: TJsonParserContext; pmValue: TObject); class procedure WriteDataBaseJson(pmWriter: TJsonWriter; pmValue: TObject; pmOptions: TTextWriterWriteObjectOptions); public property DBServerName: String read FDBServerName write FDBServerName; property DBName: String read FDBName write FDBName; property DBUser: String read FDBUser write FDBUser; property DBUserPw: Integer read FDBUserPw write FDBUserPw; property DBProvider: Integer read FDBProvider write FDBProvider; end; TDBSettings = class(TSynAutoCreateFields) private FDataBase: TDBSettingDataBase; FShorthandSymbol: TStringDynArray; public function LoadFromFile(const pmcFileName: TFileName): Boolean; procedure SaveToFile(const pmcFileName: TFileName); published property DataBase: TDBSettingDataBase read FDataBase; property ShorthandSymbol: TStringDynArray read FShorthandSymbol; end; class procedure TDBSettingDataBase.ReadDataBaseJson(var pmvContext: TJsonParserContext; pmValue: TObject); var values: array[0..4] of TValuePUtf8Char; begin if pmvContext.ParseObject(['DB-ServerName', 'DB-Name', 'DB-User', 'DB-User-Pw', 'DB-Provider'], @values) then begin with TDBSettingDataBase(pmValue) do begin DBServerName := values[0].ToString; DBName := values[1].ToString; DBUser := values[2].ToString; DBUserPw := values[3].ToInteger; DBProvider := values[4].ToInteger; end; end; end; class procedure TDBSettingDataBase.WriteDataBaseJson(pmWriter: TJsonWriter; pmValue: TObject; pmOptions: TTextWriterWriteObjectOptions); begin with TDBSettingDataBase(pmValue) do pmWriter.AddJsonEscape(['DB-ServerName', DBServerName, 'DB-Name', DBName, 'DB-User', DBUser, 'DB-User-Pw', DBUserPw, 'DB-Provider', DBProvider]); end; function TDBSettings.LoadFromFile(const pmcFileName: TFileName): Boolean; begin Result := ObjectLoadJson(Self, StringFromFile(pmcFileName)); end; procedure TDBSettings.SaveToFile(const pmcFileName: TFileName); begin FileFromString(ObjectToJson(Self), pmcFileName); end; initialization TRttiJson.RegisterCustomSerializerClass(TDBSettingDataBase, TDBSettingDataBase.ReadDataBaseJson, TDBSettingDataBase.WriteDataBaseJson);
Delphi-Quellcode:
Bis bald...
with TDBSettings.Create do
try LoadFromFile('settings.json'); ShowMessage(DataBase.DBServerName); DataBase.DBServerName := 'TestServer'; SaveToFile('settings.json'); finally Free; end; Thomas |
AW: Json Array of String: Wie Array-Items per Schleife auslesen
Diese JSON-Klassen können auch sowas wie XPath.
![]() ![]() ... |
AW: Json Array of String: Wie Array-Items per Schleife auslesen
Zitat:
Delphi-Quellcode:
Bis bald...
var
doc: TDocVariantData; begin doc.InitJsonFromFile('settings.json'); ShowMessage(doc.P['DataBase.DB-ServerName']); Thomas |
AW: Json Array of String: Wie Array-Items per Schleife auslesen
Zunächst vielen Dank!
@mytbo, Je länger ich mir das anschaue, desto mehr gefällt es mir!:thumb: Ich werde das heute Abend mal mit mORMot angehen. |
AW: Json Array of String: Wie Array-Items per Schleife auslesen
Zitat:
![]() Die mORMot Bibliothek muss nicht installiert werden. Den aktuellen Commit und die static binaries aus dem letzten Tag herunterladen. In Delphi die entsprechenden Bibliotheks- und Suchpfade setzen. Beim Erstellen hilft dieses Muster:
Code:
Die aktuelle Entwicklung ist
// Die Doppelpunkte einfach durch den Speicherpfad ersetzten
..\src;..\src\app;..\src\core;..\src\crypt;..\src\db;..\src\lib;..\src\misc;..\src\net;..\src\orm;..\src\rest;..\src\script;..\src\soa;..\src\tools\ecc;..\src\ui; ![]() ![]() Bis bald... Thomas |
AW: Json Array of String: Wie Array-Items per Schleife auslesen
Um das Ganze abzuschließen, im konkreten Fall würde es reichen, die Eigenschaftsnamen für das Lesen und Schreiben der JSON-Datei zu ändern:
Delphi-Quellcode:
Als Ausführung mit Records wie folgt:
uses
mormot.core.base, mormot.core.data, mormot.core.text, mormot.core.json, mormot.core.rtti, mormot.core.unicode, mormot.core.variants, mormot.core.os; type TDBSettingDataBase = class(TSynPersistent) private FDBServerName: String; FDBName: String; FDBUser: String; FDBUserPw: Integer; FDBProvider: Integer; published property DBServerName: String read FDBServerName write FDBServerName; property DBName: String read FDBName write FDBName; property DBUser: String read FDBUser write FDBUser; property DBUserPw: Integer read FDBUserPw write FDBUserPw; property DBProvider: Integer read FDBProvider write FDBProvider; end; TDBSettings = class(TSynAutoCreateFields) private FDataBase: TDBSettingDataBase; FShorthandSymbol: TStringDynArray; public function LoadFromFile(const pmcFileName: TFileName): Boolean; procedure SaveToFile(const pmcFileName: TFileName); published property DataBase: TDBSettingDataBase read FDataBase; property ShorthandSymbol: TStringDynArray read FShorthandSymbol; end; function TDBSettings.LoadFromFile(const pmcFileName: TFileName): Boolean; begin Result := ObjectLoadJson(Self, StringFromFile(pmcFileName)); end; procedure TDBSettings.SaveToFile(const pmcFileName: TFileName); begin FileFromString(ObjectToJson(Self), pmcFileName); end; initialization Rtti.ByClass[TDBSettingDataBase].Props.NameChanges( ['DBServerName', 'DBName', 'DBUser', 'DBUserPw', 'DBProvider'], ['DB-ServerName', 'DB-Name', 'DB-User', 'DB-User-Pw', 'DB-Provider']);
Delphi-Quellcode:
Anwendung so:
type
TDBSettingDataBase = packed record DBServerName: String; DBName: String; DBUser: String; DBUserPw: Integer; DBProvider: Integer; end; TDBSettings = packed record DataBase: TDBSettingDataBase; ShorthandSymbol: TStringDynArray; // array of String function LoadFromFile(const pmcFileName: TFileName): Boolean; procedure SaveToFile(const pmcFileName: TFileName); end; function TDBSettings.LoadFromFile(const pmcFileName: TFileName): Boolean; begin Result := RecordLoadJson(Self, StringFromFile(pmcFileName), TypeInfo(TDBSettings)); end; procedure TDBSettings.SaveToFile(const pmcFileName: TFileName); begin FileFromString(RecordSaveJson(Self, TypeInfo(TDBSettings)), pmcFileName); end; initialization Rtti.ByTypeInfo[TypeInfo(TDBSettingDataBase)].Props.NameChanges( ['DBServerName', 'DBName', 'DBUser', 'DBUserPw', 'DBProvider'], ['DB-ServerName', 'DB-Name', 'DB-User', 'DB-User-Pw', 'DB-Provider']);
Delphi-Quellcode:
Bis bald...
var
rec: TDBSettings; begin rec.LoadFromFile('settings.json'); ShowMessage(rec.DataBase.DBServerName); rec.DataBase.DBServerName := 'TestServer'; rec.SaveToFile('settings.json'); Thomas |
AW: Json Array of String: Wie Array-Items per Schleife auslesen
Diesen Ansatz mit dem JSON-Class-Mapping kann man auch ohne externe Bibliothek nur mit Delphi-Bordmitteln realisieren:
Delphi-Quellcode:
In der Anwendung sieht das dann in etwa so aus:interface uses System.Types, REST.Json.Types; // wegen des Attributs type TDBSettings = class type TDataBase = class private [JSONName('DB-Name')] FDBName: String; [JSONName('DB-Provider')] FDBProvider: Integer; FDBServerName: String; [JSONName('DB-User')] FDBUser: String; [JSONName('DB-User-Pw')] FDBUserPw: Integer; public property DBName: String read FDBName write FDBName; property DBProvider: Integer read FDBProvider write FDBProvider; property DBServerName: String read FDBServerName write FDBServerName; property DBUser: String read FDBUser write FDBUser; property DBUserPw: Integer read FDBUserPw write FDBUserPw; end; private FDatabase: TDataBase; public ShorthandSymbol: TStringDynArray; constructor Create; destructor Destroy; override; class function LoadFromFile(const pmcFileName: string): TDBSettings; procedure SaveToFile(const pmcFileName: string); property Database: TDataBase read FDatabase; end; implementation constructor TDBSettings.Create; begin inherited Create; FDatabase := TDataBase.Create(); end; destructor TDBSettings.Destroy; begin FDatabase.Free; inherited Destroy; end;
Delphi-Quellcode:
Nebenbei: Das StringArray als Feld anstatt Property ist zumindest zu hinterfragen.
uses
System.IOUtils, System.SysUtils, REST.Json; const cFileName = 'c:\temp\settings.json'; begin var settings := TJson.JsonToObject<TDBSettings>(string.Join(sLineBreak, cArr)); try TFile.WriteAllText(cFileName, TJson.ObjectToJsonString(settings)); finally settings.Free; end; begin var settings := TJson.JsonToObject<TDBSettings>(TFile.ReadAllText(cFileName)); try ... finally settings.Free; end; end; |
AW: Json Array of String: Wie Array-Items per Schleife auslesen
@mytbo,
Clonen des Repos. Pfade in den Bibliothekspfaden hinzugefügt. Ich hatte ja schon meine Unit mit 8 Klassen. Diese Unit mit deinen Vorschlägen für den Custom-Serializer ergänzt (erst einmal nur für 2 Klassen). Was soll ich sagen. Es funktioniert! :thumb: Ich bin begeistert. Und das war jetzt auch schnell umgesetzt. Natürlich verstehe ich mORMot nicht, in der Kürze der Zeit. Aber ich habe erst mal ein Ergebnis und das motiviert ja für die Zukunft. Was mir bei diesem Ansatz gefällt (ich sag's mal als Laie), dass ich eine Unit habe mit den Klassen und der Architektur. In meiner Hauptunit verwende ich dann global jeweils für jede Klasse eine neue Klassen-Instanz. Und in der Haupt-Unit gefällt mir nun die Handhabung sehr. Zumindest ist es für mich viel leichter anwendbar und lesbarer. Vielen Dank also für deinen unermüdlichen Einsatz!! @Uwe, auch dir großen Dank für deinen unermüdlichen Einsatz. Ich hatte vor deinem Post schon das Konzept von mytbo angefangen. Gute N8! :dp: |
AW: Json Array of String: Wie Array-Items per Schleife auslesen
Eine Frage noch:
Symbolisch sieht meine serialize-Klasse etwa so aus:
Delphi-Quellcode:
Bekomme ich hier die Warnmeldung noch weg?
TDBSettings = CLASS( TSynAutoCreateFields )
PRIVATE FShorthandSymbol: ARRAY [1 .. 80] OF STRING; PROCEDURE SetShorthandSymbol( CONST AIdx: Integer; CONST Value: STRING ); FUNCTION GetShorthandSymbol( CONST AIdx: Integer ): STRING; PUBLIC CONSTRUCTOR Create; // <=== hier erscheint Warnung: W1010 Methode 'Create' verbirgt virtuelle Methode vom Basistyp 'TSynAutoCreateFields' DESTRUCTOR Destroy; OVERRIDE; FUNCTION LoadFromFile( CONST pmcFileName: TFileName ): Boolean; PROCEDURE SaveToFile( CONST pmcFileName: TFileName ); PROPERTY ShorthandSymbol[CONST AIdx: Integer]: STRING READ GetShorthandSymbol WRITE SetShorthandSymbol; END; |
AW: Json Array of String: Wie Array-Items per Schleife auslesen
Entweder mit override oder, falls das nicht geht, mit reintroduce.
|
AW: Json Array of String: Wie Array-Items per Schleife auslesen
@DeddyH,
vielen Dank. :thumb: Ich habe jetzt reintroduce verwendet. Dazu habe ich noch folgende hilfreiche Seite gefunden => ![]() |
AW: Json Array of String: Wie Array-Items per Schleife auslesen
Nächstes Problem:
Ich kann in einer anderen Unit nicht auf das Property "ShorthandSymbol" zugreifen, wohl weil die Klasse von "TSynAutoCreateFields" abgeleitet ist.
Delphi-Quellcode:
Wie bekommt man das denn noch hin?
TDBSettings = CLASS( TSynAutoCreateFields )
PRIVATE FShorthandSymbol: ARRAY [1 .. 80] OF STRING; PROCEDURE SetShorthandSymbol( CONST AIdx: Integer; CONST Value: STRING ); FUNCTION GetShorthandSymbol( CONST AIdx: Integer ): STRING; PUBLIC CONSTRUCTOR Create; REINTRODUCE; DESTRUCTOR Destroy; OVERRIDE; FUNCTION LoadFromFile( CONST pmcFileName: TFileName ): Boolean; PROCEDURE SaveToFile( CONST pmcFileName: TFileName ); PROPERTY ShorthandSymbol[CONST AIdx: Integer]: STRING READ GetShorthandSymbol WRITE SetShorthandSymbol; END; |
AW: Json Array of String: Wie Array-Items per Schleife auslesen
Zitat:
|
AW: Json Array of String: Wie Array-Items per Schleife auslesen
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Die Editormeldung lautet demzufolge: E2233 Auf Eigenschaft 'ShorthandSymbol' kann hier nicht zugegriffen werden |
AW: Json Array of String: Wie Array-Items per Schleife auslesen
Zitat:
|
AW: Json Array of String: Wie Array-Items per Schleife auslesen
:oops::oops::wall::wall: Natürlich!
Danke, @jaenicke |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:29 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-2025 by Thomas Breitkreuz