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

13
demandé sur Pateman 2012-05-30 05:29:50

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
25
répondu RRUZ 2012-05-30 03:36:35

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();
    ...
6
répondu mgibsonbr 2012-05-30 02:28:55

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;
0
répondu PSyLoCKe 2016-06-05 02:21:06