Présentation de la bibliothèque d'abstraction JSON
Cette bibliothèque Delphi offre une couche d'abstraction élégante au-dessus de l'unité standard System.JSON. Elle a été conçue pour simplifier l'interaction avec les structures JSON grâce à une API fluide et fortement typée.
Caractéristiques principales
- Accès typé direct : Lecture et écriture via des propriétés indexées spécifiques (
S,I,L,F,B,D). - Gestion des dates : Conversion automatique au format ISO 8601 avec prise en charge des fuseaux horaires.
- API fluide (Fluent API) : Possibilité d'enchaîner les appels pour un code plus concis.
- Gestion mémoire automatique : Utilisation des interfaces et du comptage de références, éliminant les fuites de mémoire.
- Structures imbriquées : Création et navigation aisées dans les objets et tableaux multi-niveaux.
- Navigasion par chemin : Accès direct via des expressions de type
user.address.cityouitems.0.id. - Gestion des valeurs nulles : Méthodes dédiées pour vérifier et définir les états
null. - Extraction sécurisée : Méthodes
TryGet*pour éviter les exceptions en cas de clé manquante. - Persistance fichier : Sauvegarde et chargement directs depuis le système de fichiers.
- Aucune dépendance externe : Repose exclusivement sur la RTL de Delphi.
Guide d'utilisation
Initialisation et assignation de valeurs
uses
SimpleJSON;
var
Payload: IJson;
begin
Payload := TJson.Create;
// Assignation de données typées
Payload.S['username'] := 'Alice';
Payload.I['score'] := 150;
Payload.L['transaction_id'] := 9876543210987; // Entier 64 bits
Payload.F['balance'] := 1250.75;
Payload.B['is_verified'] := True;
Payload.D['last_login'] := Now;
// Extraction des données
WriteLn(Payload.S['username']);
WriteLn(IntToStr(Payload.I['score']));
// La libération de la mémoire est gérée automatiquement par l'interface
end;
Analyse d'une chaîne JSON
var
DataDoc: IJson;
begin
DataDoc := TJson.Parse('{"product_id":502,"label":"Clavier","cost":45.50}');
if Assigned(DataDoc) then
WriteLn(DataDoc.S['label']); // Affiche: Clavier
end;
Traitement des dates et heures
var
EventData: IJson;
begin
EventData := TJson.Create;
// Les valeurs TDateTime sont sérialisées en ISO 8601
EventData.D['start_date'] := Now;
EventData.D['birth_date'] := EncodeDate(1985, 8, 20);
WriteLn(DateTimeToStr(EventData.D['start_date']));
// Analyse d'une chaîne avec fuseau horaire
EventData := TJson.Parse('{"meeting":"Sync","timestamp":"2024-03-10T14:00:00+01:00"}');
WriteLn(DateTimeToStr(EventData.D['timestamp']));
end;
Formats de date reconnus :
- ISO 8601 avec millisecondes :
2024-03-10T14:00:00.000 - ISO 8601 standard :
2024-03-10T14:00:00 - Avec décalage horaire :
2024-03-10T14:00:00+01:00 - Indicateur UTC :
2024-03-10T14:00:00Z - Date seule :
2024-03-10
Gestion des valeurs nulles
var
RecordJson: IJson;
begin
RecordJson := TJson.Create;
RecordJson.SetNull('cancellation_date');
if RecordJson.IsNull('cancellation_date') then
WriteLn('La date d''annulation est nulle');
// Null dans un tableau
RecordJson.A['events'].AddNull;
if RecordJson.A['events'].IsNull(0) then
WriteLn('Le premier événement est nul');
end;
Extraction sécurisée (TryGet)
var
UserData: IJson;
CityName: string;
UserAge: Integer;
begin
UserData := TJson.Parse('{"city":"Lyon","age":32}');
if UserData.TryGetS('city', CityName) then
WriteLn('Ville: ' + CityName);
if UserData.TryGetI('age', UserAge) then
WriteLn('Âge: ' + IntToStr(UserAge));
if not UserData.TryGetS('email', CityName) then
WriteLn('Clé manquante');
end;
Objets et tableaux imbriqués
var
Profile: IJson;
Idx: Integer;
begin
Profile := TJson.Create;
// Création implicite d'objets imbriqués
Profile.O['location'].S['country'] := 'France';
Profile.O['location'].S['postal_code'] := '69000';
WriteLn(Profile.O['location'].S['country']);
// Manipulation de tableaux avec chaînage
Profile.A['skills']
.Add('Delphi')
.Add('C++')
.Add('SQL');
for Idx := 0 to Profile.A['skills'].Count - 1 do
WriteLn(Profile.A['skills'].S[Idx]);
// Ajout d'objets dans un tableau
Profile.A['contacts'].AddObject.S['type'] := 'email';
Profile.A['contacts'].O[0].S['value'] := 'alice@example.com';
end;
Accès par chemin (Path)
var
Config: IJson;
begin
Config := TJson.Create;
Config.S['app_name'] := 'MonApp';
Config.O['database'].S['host'] := 'localhost';
Config.A['ports'].Add(8080).Add(8443);
WriteLn(Config.Path['app_name']); // MonApp
WriteLn(Config.Path['database.host']); // localhost
WriteLn(Config.Path['ports.1']); // 8443
end;
Persistance sur disque
var
Settings: IJson;
begin
Settings := TJson.Create;
Settings.S['theme'] := 'dark';
Settings.I['timeout'] := 30;
Settings.SaveToFile('app_config.json');
// Rechargement
Settings := TJson.LoadFromFile('app_config.json');
WriteLn(Settings.S['theme']);
end;
Référence de l'API
Interface IJson
| Membre | Descriptoin |
|---|---|
S[Key] |
Lecture/écriture de chaînes |
I[Key] |
Lecture/écriture d'entiers 32 bits |
L[Key] |
Lecture/écriture d'entiers 64 bits |
F[Key] |
Lecture/écriture de nombres à virgule flottante |
B[Key] |
Lecture/écriture de booléens |
D[Key] |
Lecture/écriture de dates (ISO 8601) |
O[Key] |
Accès à un sous-objet |
A[Key] |
Accès à un tableau |
Path[Expr] |
Navigation par chemin |
IsNull(Key) |
Vérifie si la valeur est nulle |
SetNull(Key) |
Définit la valeur comme nulle |
TryGet*(...) |
Méthodes d'extraction sécurisée (S, I, L, F, B, D) |
Contains(Key) |
Vérifie l'existence d'une clé |
Remove(Key) |
Supprime une clé |
Clear |
Vide l'objet |
GetKeys |
Retourne la liste des clés |
Count |
Nombre de propriétés |
ToJSON |
Sérialisation compacte |
Format |
Sérialisation formatée (indentée) |
SaveToFile |
Écriture dans un fichier |
Interface IJsonArray
| Membre | Description |
|---|---|
S/I/L/F/B/D[Index] |
Accès typé aux éléments du tableau |
O[Index] |
Accès à un objet dans le tableau |
IsNull(Index) |
Vérifie si un élément est nul |
Add(Value) |
Ajoute un élément (retourne Self pour chaînage) |
AddNull |
Ajoute une valeur nulle |
AddObject |
Ajoute et retourne un nouvel objet |
AddArray |
Ajoute et retourne un nouveau tableau |
Delete(Index) |
Supprime un élément |
Clear |
Vide le tableau |
Count |
Nombre d'éléments |
ToJSON / Format |
Sérialisation du tableau |
Méthodes de classe
| Méthode | Description |
|---|---|
TJson.Create |
Instancie un objet JSON vide |
TJson.Parse |
Analyse une chaîne JSON |
TJson.ParseFile / LoadFromFile |
Charge et analyse un fichier JSON |
TJsonArray.Create |
Instancie un tableau JSON vide |
TJsonArray.Parse |
Analyse une chaîne de tableau JSON |
Comparaison avec l'API native System.JSON
Approche native
var
NativeObj: TJSONObject;
begin
NativeObj := TJSONObject.Create;
try
NativeObj.AddPair('username', TJSONString.Create('Alice'));
NativeObj.AddPair('score', TJSONNumber.Create(150));
WriteLn(NativeObj.GetValue<string>('username'));
finally
NativeObj.Free;
end;
end;
Approche avec la bibliothèque d'abstraction
var
WrapperDoc: IJson;
begin
WrapperDoc := TJson.Create;
WrapperDoc.S['username'] := 'Alice';
WrapperDoc.I['score'] := 150;
WriteLn(WrapperDoc.S['username']);
// Libération automatique, pas de bloc try..finally requis
end;
Configuration et compilation
Ce composant nécessite Delphi 10.4 Sydney ou une version ultérieure, et cible les plateformes Win32 et Win64.
Structure du projet :
json_wrapper/
├── SimpleJSON.pas # Unité principale de la bibliothèque
├── SimpleJSONDemo.dpr # Projet de démonstration
└── README.md # Documentation technique
Compilation via la ligne de commande :
dcc32 SimpleJSONDemo.dpr