David Schwartz 426 Posted November 23, 2022 I'm playing with SuperObject for the first time and the example refers to paths but there's something (a lot) that's unclear to me. (It could use more examples.) { "success": true, "data": { "voices_list": [ { "Engine": "neural", "VoiceId": "ai2-Stacy", "VoiceGender": "Female", "VoiceWebname": "Stacy", "Country": "US", "Language": "en-US", "LanguageName": "English, US", "VoiceEffects": [ ] }, { "Engine": "neural", "VoiceId": "ai1-Matthew", "VoiceGender": "Male", "VoiceWebname": "Matthew", "Country": "US", "Language": "en-US", "LanguageName": "English, US", "VoiceEffects": [ "news" ] }, {...} ], "count": 50 } } This JSON response packet has two items: success and data. data has two items: voices_list and count The VoiceEffects is mostly empty, but sometimes has one or more items in it. I basically want to create an object from this Initially, I'm trying to figure out how to get the count in voices_list. There should be two ways: 1) should be via data.count, but all I ever get is zero 2) I'd think there's a way to ask for how many elements are in the voices_list array, which should be 50 in this case, but I can't figure out how to get that count. obj := SO(RESTResponse1.Content); obj.AsObject.S['success'] --> true but obj.AsObject.I['data.count'] --> 0 (zero) What am I missing? Share this post Link to post
Davide Angeli 44 Posted November 23, 2022 This should work: Obj.O['data'].I['count'] 1 Share this post Link to post
David Schwartz 426 Posted November 23, 2022 (edited) 9 hours ago, Davide Angeli said: This should work: Obj.O['data'].I['count'] BINGO! The example shows ['xx.yy'] but that doesn't work, and using obj.O[___].I[___] didnt' occur to me This works: resp.success := obj.AsObject.S['success']; resp.count := obj.O['data'].I['count']; // because this element happens to exist resp.count := obj.O['data'].O['voices_list'].AsArray.Length; // this queries the array directly Edited November 23, 2022 by David Schwartz Share this post Link to post
Davide Angeli 44 Posted November 24, 2022 I used JSON superobject for a while and it's good but in cases like this I prefer the very good Delphi NEON library so I could deserialize the JSON directly to Delphi objects. With NEON in a case like yours I could do something like this: Type TVoice = record public Engine : String; VoiceId : String; VoiceGender : String; // .. other fields end; TVoicesData = record public voices_list : TArray<TVoice>; count : Integer; end; TVoices = record public success : Boolean; data : TVoicesData; end; procedure TForm1.Button2Click(Sender: TObject); begin var sJson:= '{'+ ' "success": true,'+ ' "data": {'+ ' "voices_list": ['+ ' {'+ ' "Engine": "neural",'+ ' "VoiceId": "ai2-Stacy",'+ ' "VoiceGender": "Female",'+ ' "VoiceWebname": "Stacy",'+ ' "Country": "US",'+ ' "Language": "en-US",'+ ' "LanguageName": "English, US",'+ ' "VoiceEffects": ['+ ' ]'+ ' },'+ ' {'+ ' "Engine": "neural",'+ ' "VoiceId": "ai1-Matthew",'+ ' "VoiceGender": "Male",'+ ' "VoiceWebname": "Matthew",'+ ' "Country": "US",'+ ' "Language": "en-US",'+ ' "LanguageName": "English, US",'+ ' "VoiceEffects": ['+ ' "news"'+ ' ]'+ ' }'+ ' ],'+ ' "count": 50'+ ' }'+ '}'; var Voices:=DeserializeValueTo<TVoices>(sJson); for var Voice in Voices.data.voices_list do ListBox1.Items.Add(Voice.Engine+' - '+Voice.VoiceGender); end; function TForm1.DeserializeValueTo<T>(const aJSON : String): T; begin if FNeonConfig=Nil then FNeonConfig:=TNeonConfiguration.Default; var LJSON := TJSONObject.ParseJSONValue(aJSON); try var LReader:=TNeonDeserializerJSON.Create(FNeonConfig); try var LValue:=LReader.JSONToTValue(LJSON, TRttiUtils.Context.GetType(TypeInfo(T))); Result:=LValue.AsType<T>; finally LReader.Free; end; finally LJSON.Free; end; end; 2 Share this post Link to post