Jump to content
David Schwartz

JSON superobject question

Recommended Posts

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
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 by David Schwartz

Share this post


Link to post

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;

 

  • Like 2

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×