Comment analyser un objet JSON imbriqué dans Delphi XE2?
je suis nouveau à JSON et j'ai ce projet sur mes mains qui me demandent de parser un JSON et d'afficher certains de ses contenus dans un ListView. Le problème est que la documentation que j'ai lue à ce jour traitait des objets JSON contenant des tableaux JSON, alors que mon cas concerne les objets imbriqués. Pour faire court, voici le résumé: J'utilise Delphi XE2 avec DBXJSON. Je poste quelques valeurs à un serveur et il répond avec un objet JSON qui ressemble à ça:
{
"products": {
"Men's Sneakers": {
"instock": false,
"size": "423",
"manufacturer": "Adidas",
"lastcheck": "20120529"
},
"Purse": {
"instock": true,
"size": "not applicable",
"manufacturer": "Prada",
"lastcheck": "20120528"
},
"Men's Hood": {
"instock": false,
"size": "M",
"manufacturer": "Generic",
"lastcheck": "20120529"
}
},
"total": 41,
"available": 30
}
Ce Que Je voulu faire, c'est d'avoir chaque élément (c'est à dire Sac à main) analysé et ajouté en légende, dans une liste, avec un seul point (le fabricant). J'ai créé une procédure qui prend la chaîne JSON comme argument, créé l'objet JSON, mais je ne sais pas comment analyser les objets imbriqués.
procedure TForm1.ParseString(const AString: string);
var
json : TJSONObject;
jPair : TJSONPair;
jValue : TJSONValue;
jcValue : TJSONValue;
l,i : Integer;
begin
json := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(AString),0) as TJSONObject;
try
//get the pair to evaluate in this case the index is 1
jPair := json.Get(1);
{further process the nested objects and adding them to the listview}
finally
json.Free;
end;
end;
Toutes les suggestions sont grandement appréciés. J'ai perdu pas mal de temps à essayer d'obtenir les tenants et les aboutissants de JSON à Delphi sans succès.
Merci, sphynx
3 réponses
cet exemple
{$APPTYPE CONSOLE}
{$R *.res}
uses
DBXJSON,
System.SysUtils;
Const
StrJson=
'{'+
' "products": {'+
' "Men''s Sneakers": {'+
' "instock": false,'+
' "size": "423",'+
' "manufacturer": "Adidas",'+
' "lastcheck": "20120529"'+
' },'+
' "Purse": {'+
' "instock": true,'+
' "size": "not applicable",'+
' "manufacturer": "Prada",'+
' "lastcheck": "20120528"'+
' },'+
' "Men''s Hood": {'+
' "instock": false,'+
' "size": "M",'+
' "manufacturer": "Generic",'+
' "lastcheck": "20120529"'+
' }'+
' },'+
' "total": 41,'+
' "available": 30'+
'}';
procedure ParseJson;
var
LJsonObj : TJSONObject;
LJPair : TJSONPair;
LProducts : TJSONValue;
LProduct : TJSONValue;
LItem : TJSONValue;
LIndex : Integer;
LSize : Integer;
begin
LJsonObj := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(StrJson),0) as TJSONObject;
try
LProducts:=LJsonObj.Get('products').JsonValue;
LSize:=TJSONArray(LProducts).Size;
for LIndex:=0 to LSize-1 do
begin
LProduct := TJSONArray(LProducts).Get(LIndex);
LJPair := TJSONPair(LProduct);
Writeln(Format('Product Name %s',[LJPair.JsonString.Value]));
for LItem in TJSONArray(LJPair.JsonValue) do
begin
if TJSONPair(LItem).JsonValue is TJSONFalse then
Writeln(Format(' %s : %s',[TJSONPair(LItem).JsonString.Value, 'false']))
else
if TJSONPair(LItem).JsonValue is TJSONTrue then
Writeln(Format(' %s : %s',[TJSONPair(LItem).JsonString.Value, 'true']))
else
Writeln(Format(' %s : %s',[TJSONPair(LItem).JsonString.Value, TJSONPair(LItem).JsonValue.Value]));
end;
end;
finally
LJsonObj.Free;
end;
end;
begin
try
ParseJson;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
retour
Product Name Men's Sneakers
instock : false
size : 423
manufacturer : Adidas
lastcheck : 20120529
Product Name Purse
instock : true
size : not applicable
manufacturer : Prada
lastcheck : 20120528
Product Name Men's Hood
instock : false
size : M
manufacturer : Generic
lastcheck : 20120529
ce site décrit le type TJSONValue
plus de détails. Si vos données est un objet, il aura le type TJSONObject
, donc vérifiez son API pour voir comment procéder.
je crois que la première chose dont vous avez besoin pour effectuer une itération sur ses paires (utiliser GetEnumerator
si vous ne connaissez pas les noms des clés, sinon utilisez simplement leGet
- passage d'une chaîne au lieu d'un nombre). Pour chaque paire, la clé sera une chaîne simple (tapez TJSONString
) et la valeur peut être n'importe TJSONValue
. Répéter jusqu'à ce que vous atteigniez les feuilles.
Exemple:
products := jPair.Get('products');
purse := products.GetJsonValue().Get('Purse');
purseManuf := purse.GetJsonValue().Get('manufacturer');
...
Ou si vous ne savez pas quels produits sont les suivants:
products := jPair.Get('products');
for prodPair in products.GetEnumerator() do
begin
prodName := prodPair.GetJsonString();
prodObj := prodPair.GetJsonValue();
...
montre une façon très moderne et simple de convertir JSON:
uses REST.JSON; // Also new System.JSON
procedure TForm1.Button1Click(Sender: TObject);
var
Foo: TFoo;
begin
Foo := TFoo.Create;
try
Foo.Foo := 'Hello World';
Foo.Fee := 42;
Memo1.Lines.Text := TJson.ObjectToJsonString(Foo);
finally
Foo.Free;
end;
Foo := TJson.JsonToObject<TFoo>(Memo1.Lines.Text);
try
Foo.Fee := 100;
Memo1.Lines.Add(TJson.ObjectToJsonString(Foo));
finally
Foo.Free;
end;
end;