Newsgroup: it.comp.lang.delphi
Titolo: JSON in quale oggetto Delphi lo trasformo e come?

Ciao a tutti,
ho una funzione Delphi alla quale arrivano oggetti JSON fatti in
questo modo:
'{"1":"10","2":"510"}'
oppure
'{"1":"10","2":"510", "10":"625"}'
ovvero sono coppie di stringhe (contenenti solo caratteri numerici).
Ho bisogno di trasformarlo in un qualche oggetto Delphi in modo tale
che sia possibile in un ciclo passare in rassegna tutte le coppie di
stringhe contenute nel JSON. Mi potete aiutare o dare qualche indizio?
Grazie

 che sia possibile in un ciclo passare in rassegna tutte le coppie
 
TStringList
 
A.
 
 

 stringhe contenute nel JSON. Mi potete aiutare o dare qualche indizio?
 
Hai provato questo?
http://sourceforge.net/projects/is-webstart/
 
e questo?
http://sourceforge.net/projects/lkjson/
 
e questo?
http://www.progdigy.com/?page_id=6
 
 
-- 
morde
QT 4.7
Delphi (5,6,7.. expired)
Firebird Database

Opzione ed ho dichiarato pcb in questo modo:
pcb = {productid: null, widthmm: null, heightmm: null, productiondays:
null, quantity: null, filename: null, customer_code: null,
customer_note: null, attributes: {}};
Quando questo JSON arriva a Delphi, faccio:
SelectedAttributesJSON := TJSONObject.Create;
SelectedAttributesJSON.AddPair('attributes',
jObject.Get('attributes').JsonValue);
Ok la stringlist con uso di coppie nome valore (usando il simbolo
'='), ma mi sono un po' arenato perchè non so come scorrere tutti gli
elementi di questo oggetto JSON ...
Non sempre sono disponibili tutti gli attributi per tutti i prodotti,
e quindi dell'attributo con id=1 il cliente

 e quindi dell'attributo con id=1 il cliente
Ti si � troncato il messaggio?
Concordo con tutta l'implementazione.
Il problema resta quello di usare delle classi wrapper che ti permettono 
di attraversare la struttura.
Nei link che ti ho fornito trovi le classi da usare per fare questo.
BTW, i link sono stati ricavati dal sito stesso di json, quindi presumo 
che siano attendibili.


 wrote:

Grazie, gli sto dando un'occhiata per vedere come funzionano. Appena
ho fatto posto le righe di codice per scorrere l'oggetto ...

 stringhe contenute nel JSON. Mi potete aiutare o dare qualche indizio?
 
Che versione di Delphi possiedi?
In quelle recenti vi sono classi specifiche dedicate a JSON.
 
Ciao!
  Marco.
 
-- 
Marco Breveglieri
   (
http://www.marco.breveglieri.name
)

    (
http://www.marco.breveglieri.name
)
 
Delphi XE Enterprise
 
Si, ci sono le librerie JSON ma non riesco a trovare documentazione.
Riesco con il metodo Get a tirar fuori un TJSONObject da un'altro, ma
poi non so come impostare un ciclo per scorrere tutti gli elementi ...
sto andando un po' a tentoni.

 sto andando un po' a tentoni.
Hai dato un'occhiata qui?
http://docwiki.embarcadero.com/RADStudio/en/JSON
Osserva anche il codice sorgente della libreria VCL per una 
dichiarazione completa dei membri disponibili.
Ciao,



 
Ciao Marco,
 
si, riesco a creare oggetti JSON senza problemi, ed ho capito come, ad
esempio, andare a pescare il valore della tal chiave. Il mio problema
però è diverso. Mi arriva un oggetto tipo questo:
 
'{"productid":"4","widthmm":"100","heightmm":"100","productiondays":
11,"quantity":
100,"filename":null,"customer_code":null,"customer_note":null,"attributes":
{"1":"20","2":"510"}}'
 
Io devo scorrere tutti i valori contenuti nella coppia chiave/valore
dal nome attributes:
 
"attributes":{"1":"20","2":"510"}
 
Posso ottenere un TJSONPair con
 
MyJSONPair := MyJSONObject.Get('attributes');
 
oppure posso ottenerne il TJSONValue con:
 
MyJSONValue := MyJSONObject.Get('attributes').JsonValue;
 
oppure ottenerne la stringa con la sintassi JSON:
 
MyJSONString := MyJSONObject.Get('attributes').JsonValue.ToString;
 
Ma non capisco come posso, in generale, prendere gli elementi
contenuti nell'oggetto JSON la cui stringa è questa:
 
{"1":"20","2":"510"}
 
uno ad uno.
 
Ci sono andato vicino con l'utilizzo di JSON SuperObject (http://
www.progdigy.com/?page_id=6
), ma mi tira fuori solo il primo elemento,
utilizzando il costrutto indicato nel file di Help, alla voce
"Browsing object properties without enumerator":
 
var
  item: TSuperObjectIter;
begin
  if ObjectFindFirst(obj, item) then
  repeat
    item.key;
    item.val;
  until not ObjectFindNext(item);
  ObjectFindClose(item);
 
 

Alla fine ci sono riuscito, come avevo scritto alla fine del post
precedente, con l'utilizzo di JSON SuperObject (http://
www.progdigy.com/?page_id=6
).
 
Non riesco a convincermi che non ci fosse la possibilità di farlo con
le librerie JSON di Delphi.
 
In ogni caso ho fatto così:
 
var
  Obj: ISuperObject;
  item: TSuperObjectIter;
  jString: String;
  AttributeList: TStringList;
begin
  [...]
  jString := jObject.Get('attributes').JsonValue.ToString;
  Obj := SO(jString);
  AttributeList := TSTringList.Create;
 
  if ObjectFindFirst(obj, item) then
  repeat
    AttributeList.Add(item.key + '=' + item.val.AsString);
  until not ObjectFindNext(item);
  ObjectFindClose(item);
 
  [...]
 
In questo modo ottengo una stringlist con le coppie Nome/Valore
separate da un simbolo =
 
Grazie a tutti per l'aiuto.

Grazie a Marco Cantù riporto anche il metodo per ottenere la stessa
cosa con la libreria Delphi DBXJson.pas:
 
var
  i: Integer;
  attrObject: TJSONObject;
  AttributeList: TStringList;
begin
  [...]
  AttributeList := TStringList.Create;
  jString := jObject.Get('attributes').JsonValue.ToString;
  if jObject.Get('attributes').JsonValue is TJSONObject then
  begin
    attrObject := TJSONObject(jObject.Get('attributes').JsonValue);
    for I := 0 to attrObject.Size - 1 do
      AttributeList.Add(attrObject.Get (I).JsonString.ToString + '=' +
        attrObject.Get (I).JsonString.ToString);
  end;
  [...]
 
Io non ci arrivavo ... e 'sta libreria JSON è per me ostica.

Il codice del post precedente contiene un paio di errori. Il primo è
che con il metodo ToString si ottiene una stringa tra doppi apici,
quindi gli elementi della stringlist contengono anche questo carattere
all'inizio e alla fine (es. "1" anzichè 1). Occorre usare invece la
proprietà Value che restituisce una stringa senza doppi apici.
Il secondo errore è che la stringlist viene costruita con coppie Nome/
Nome anzichè Nome/Valore.
Il codice corretto è il seguente:
var
  i: Integer;
  attrObject: TJSONObject;
  AttributeList: TStringList;
begin
  [...]
  AttributeList := TStringList.Create;
  if jObject.Get('attributes').JsonValue is TJSONObject then
  begin
    attrObject := TJSONObject(jObject.Get('attributes').JsonValue);
    for I := 0 to attrObject.Size - 1 do
      AttributeList.Add(attrObject.Get(I).JsonString.Value + '=' +
        attrObject.Get(I).JsonValue.Value);
  end;
  [...]

Chiedo scusa per il ritardo nella risposta, purtroppo ho avuto parecchio da fare in questi giorni, ma volevo prendermi un attimo per analizzare il problema, anche perché il codice che hai scritto mi sembrava molto complicato.
 
Usando la "trial" di XE2, io ho scritto questo pezzo di codice che sostanzialmente carica da un file esterno (Data.json) l'esempio di dati che hai riportato e, al clic su un pulsante, con un ciclo, mostra in un "TMemo" le chiavi e i valori corrispondenti:
 
 
 
uses
  DBXJSON, IOUtils;
 
procedure TForm2.Button1Click(Sender: TObject);
var
  JSONData: string;
  JSONObject: TJSONValue;
  JSONPair: TJSONPair;
begin
  JSONData := TFile.ReadAllText('C:\Temp\Data.json');
  JSONObject := TJSONObject.ParseJSONValue(JSONData);
  for JSONPair in TJSONObject(JSONObject) do
  begin
    Memo1.Lines.Add(Format('%s = %s',
     [JSONPair.JsonString.Value,
      JSONPair.JsonValue.Value]));
  end;
end;
 
 
 
Questo codice funziona regolarmente senza particolari problemi, quindi secondo me - approfondendo bene l'uso delle classi - è senz'altro possibile semplificarlo ulteriormente senza ricorrere alla caterva di oggetti che hai impiegato. :)
