Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

JSON in quale oggetto Delphi lo trasformo e come?

404 views
Skip to first unread message

fran...@mdsrl.it

unread,
Sep 9, 2011, 6:23:39 AM9/9/11
to
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

Alberto Salvati

unread,
Sep 9, 2011, 6:46:57 AM9/9/11
to
> ho una funzione Delphi alla quale arrivano oggetti JSON fatti in
> questo modo:

Arrivano da dove, per curiosita'?


> Ho bisogno di trasformarlo in un qualche oggetto Delphi in modo tale
> che sia possibile in un ciclo passare in rassegna tutte le coppie

TStringList

A.


morde

unread,
Sep 9, 2011, 7:03:43 AM9/9/11
to
On 09.09.2011 12:23, fran...@mdsrl.it wrote:
> 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?

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

fran...@mdsrl.it

unread,
Sep 9, 2011, 7:03:46 AM9/9/11
to

Arrivano da una chiamata REST fatta tramite JavaScript (Delphi Relax).

Io JSON non lo digerisco ... array o oggetti per me, pari sono.

In pratica, in una pagina di scelta delle opzioni disponibili per un
determinato prodotto, uso un oggetto JSON per far conoscere alla mia
applicazione Delphi, quali sono le opzioni che il cliente ha scelto.

Quindi il JSON che avevo, prima di introdurre le opzioni, conteneva
l'id del prodotto ed altre informazioni necessarie alla determinazione
del prezzo. Questa la sua dichiarazione in Javascript:

pcb = {productid: null, widthmm: null, heightmm: null, productiondays:
null, quantity: null, filename: null, customer_code: null,
customer_note: null};

Poi, introducendo attributi e opzioni, è sorta l'esigenza di tenere
traccia delle opzioni scelte dal cliente per ogni attributo, quindi ho
pensato, avendo a disposizione un solo oggetto JSON per la chiamata
REST, di aggiungere all'oggetto una lista di coppie Attributo<-
>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

morde

unread,
Sep 9, 2011, 7:27:13 AM9/9/11
to
On 09.09.2011 13:03, fran...@mdsrl.it wrote:

> Non sempre sono disponibili tutti gli attributi per tutti i prodotti,
> 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.

fran...@mdsrl.it

unread,
Sep 9, 2011, 7:35:02 AM9/9/11
to
On 9 Set, 13:27, morde <mo...@mailinator.com> wrote:

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

Marco Breveglieri

unread,
Sep 9, 2011, 8:54:22 AM9/9/11
to
Il giorno venerdì 9 settembre 2011 12:23:39 UTC+2, [nessun nome] ha scritto:
> ho una funzione Delphi alla quale arrivano oggetti JSON fatti in
> questo modo:
> [...]
> 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?

Che versione di Delphi possiedi?
In quelle recenti vi sono classi specifiche dedicate a JSON.

Ciao!
Marco.

--
Marco Breveglieri
(http://www.marco.breveglieri.name)

fran...@mdsrl.it

unread,
Sep 9, 2011, 11:17:40 AM9/9/11
to
On 9 Set, 14:54, Marco Breveglieri <bre...@gmail.com> wrote:
> Il giorno venerdì 9 settembre 2011 12:23:39 UTC+2, [nessun nome] ha scritto:
>
[...]
> Che versione di Delphi possiedi?
> In quelle recenti vi sono classi specifiche dedicate a JSON.
>
> Ciao!
>   Marco.
>
> --
> Marco Breveglieri
>    (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.

Marco Breveglieri

unread,
Sep 10, 2011, 9:21:25 AM9/10/11
to
Il 09/09/2011 17:17, fran...@mdsrl.it ha scritto:
> 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.

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,

fran...@mdsrl.it

unread,
Sep 12, 2011, 8:54:06 AM9/12/11
to
On 10 Set, 15:21, Marco Breveglieri <bre...@gmail.com> wrote:
[...]
> Hai dato un'occhiata qui?http://docwiki.embarcadero.com/RADStudio/en/JSON
>

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);


fran...@mdsrl.it

unread,
Sep 12, 2011, 9:21:21 AM9/12/11
to
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.

fran...@mdsrl.it

unread,
Sep 13, 2011, 9:28:35 AM9/13/11
to
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.

fran...@mdsrl.it

unread,
Sep 14, 2011, 3:39:04 AM9/14/11
to
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;
[...]

Marco Breveglieri

unread,
Sep 15, 2011, 1:15:47 PM9/15/11
to
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. :)
0 new messages