Jump to content
amit

How to get json array from string?

Recommended Posts

I try to retreive the data from JSON string that return from the server. Here is the JSON String

{"RESULT":200, "IDLIST":[1,2,3,4,5]}

I wrote delphi code as shown below to get the Array but it return empty string.

var
  jso: TJsonObject;
  jsv: TJsonValue;
  s, RetResult, RetIDList: string;
begin
  s := '{"RESULT":200, "IDLIST":[1,2,3,4,5]}';
  jso := TJsonObject.ParseJSONValue(s) as TJsonObject;
  jsv := jso.GetValue('RESULT');
  if jsv<>nil then RetResult := jsv.Value else RetResult := '';   // <-- this is OK.  RetResult will be '200'.
  jsv := jso.GetValue('IDLIST');
  if jsv<>nil then RetIDList := jsv.Value else RetIDList := '';  // <---I alway get the empty string for RetIDList.
end;

I try to use jsonpair instead with the code below. I will get the array string.
 

var
  jso: TJsonObject;
  jsv: TJsonValue;
  jsp: TJsonpair;
  s, RetResult, RetIDList: string;
begin
  s := '{"RESULT":200, "IDLIST":[1,2,3,4,5]}';
  jso := TJsonObject.ParseJSONValue(s) as TJsonObject;
  jsv := jso.GetValue('RESULT');
  if jsv<>nil then RetResult := jsv.Value else RetResult := '';   // <-- this is OK.  RetResult will be '200'.

  for iJsonPair in jso do
  begin
    if (iJsonPair.JsonString.value = 'IDLIST') then
    begin
      RetIDList := iJsonPair.JsonValue.ToJson;    // <-- This is OK. RetIDList wlll be '[1,2,3,4,5]'.
      // RetIDList := iJsonPair.JsonValue.Value;  // <-- if I use this line instead I got empty string;
      break;
    end;
  end;
end;
Why?
What is the different between iJsonPair.JsonValue.ToJson and iJsonPair.JsonValue.Value ?
 
 

Share this post


Link to post

I want to use them to construct the SQL to update record flag in SQL table.   The Bracket in the RetIDList will be romoved and finally the RetIDList will be '1,2,3,4,5'.   Then I will create Update SQL as 
 

  qry.SQL.clear;
  qry.SQL.add('Update Table1 Set Flag=0 where ID in ('+RetIDList+');'); 
  qry.ExecSql;

Anyway,  if you can point me how to access IDLIST as an array of integer it will be OK.  I can generate the SQL from that array.

Share this post


Link to post
18 minutes ago, amit said:

if you can point me how to access IDLIST as an array of integer it will be OK

Declare a class like this and create an instance with TJson.JsonToObject from REST.Json.pas:

type
  TMyJson = class
    FResult: Integer;
    FIdList: TArray<Integer>;
  end;

const
  cJson = '{"RESULT":200, "IDLIST":[1,2,3,4,5]}';
var
  myJson: TMyJson;
begin
  myJson := TJson.JsonToObject<TMyJson>(cJson);
  try
    for var I := 0 to Length(myJson.FIdList) - 1 do
    { do something with myJson.FIdList[I] }
  finally
    myJson.Free;
  end;
end;

 

  • Like 2

Share this post


Link to post
On 2/27/2021 at 2:44 AM, amit said:

I wrote delphi code as shown below to get the Array but it return empty string.

That is because IDLIST is an array (of integers), but you are trying to read it as a string.  jso.GetValue('IDLIST') will return a TJSONValue pointer to a TJSONArray, which does not implement the Value() method, so it returns a blank string.  You need to type-cast the TJSONValue to TJSONArray and enumerate its elements, eg:

var
  jso: TJsonObject;
  jsa: TJSONArray;
  s, RetIDList: string;
  i: Integer;
begin
  s := '{"RESULT":200, "IDLIST":[1,2,3,4,5]}';
  jso := TJsonObject.ParseJSONValue(s) as TJsonObject;
  if jso <> nil then
  try
    ...
    RetIDList := '';
    jsa := jso.GetValue('IDLIST') as TJSONArray;
    if jsa <> nil then
    begin
      if jsa.Count > 0 then
      begin
        RetIDList := jsa[0].Value;
        for i := 1 to jsa.Count-1 do
          RetIDList := RetIDList + ',' + jsa[i].Value;
      end;
    end;
    ...
  finally
    jso.Free;
  end;
end;

 

Edited by Remy Lebeau
  • Like 1

Share this post


Link to post
var jsonString = '{"x": {"y": [2,3]}, "t": [3,5]}';
var obj = JSON.parse(jsonString);
var arr = [];
arr.push(obj.x.y)
arr.push(obj.t)
console.log(arr);

I was wondering the same thing when I was working on https://www.slotozilla.com/free-slots/silver-lion .Don't create your json yourself, most languages have functions to turn your object/array into a valid json, so just create your object as you normally do and then use that function as in Javascript JSON.stringify().

Edited by Howells
misspelled the point
  • Like 1

Share this post


Link to post
On 2/27/2021 at 12:59 PM, amit said:

I want to use them to construct the SQL to update record flag in SQL table.   The Bracket in the RetIDList will be romoved and finally the RetIDList will be '1,2,3,4,5'.   Then I will create Update SQL as 
 


  qry.SQL.clear;
  qry.SQL.add('Update Table1 Set Flag=0 where ID in ('+RetIDList+');'); 
  qry.ExecSql;

 

Just two notices. If you will ever use Oracle and RetIDList will contain more than 1000 elements, the code will fail. I don't know if any other RDBMS has this limitation though.

How trusted is the file? Taking a string value from somewhere and putting it in a SQL command exposes your application to injection attacks.

  • Like 2

Share this post


Link to post
22 hours ago, aehimself said:

Just two notices. If you will ever use Oracle and RetIDList will contain more than 1000 elements, the code will fail. I don't know if any other RDBMS has this limitation though.

How trusted is the file? Taking a string value from somewhere and putting it in a SQL command exposes your application to injection attacks.

I limit the data send to server at 25 records at a time.     Anyway I wonder how I can make sure that the server can successfully insert the whole data on the database without returning the successfully inserted ID.   if I just check only the http status 200 returned, I knew only that the server successfully received the whole json string but it is not guarantee that the whole data are inserted successfully on the database.    In my server code, I return just only the successfully inserted record IDs, the problem ones will not be returned.  The client will update the sentflag on any records that ID are in the RetIDList.   So on the next data send phase, the problem ones can be sent again.  

 

Is there any other way to check whether there is no problem at all on the server side?     Please suggest.   Thank you.

 

Oh another thing the IDs that send to the server in Json string is the ID of the records in database's table in the client PC and it will never be inserted to the Server's database for any reference.   They will be used for server to reply back to the client if they are inserted succesfully.  Client will mark those records by setting sentflag so no need to resend them.

Edited by amit
add some clarify message

Share this post


Link to post
8 hours ago, amit said:

Is there any other way to check whether there is no problem at all on the server side?     Please suggest.   Thank you.

Well, I have 2 ideas. 1 - use the HTTP status codes. 200 means all fine, it was inserted. 500 means an error happened, transaction was rolled back, resend is needed from the client.

If you can not control the status codes, you can add a "status check API". After a 200 OK for inserting the record, the client can query the inserted IDs for verification.

If I understand the question completely, that is.

 

But, I never really worked with stuff like this so take this with a grain of salt. I always liked to control everything, so when it was needed I launched my own webserver via ICS. That way I could set return codes, headers, session cookies, and even send detailed answers in any format whenever I wanted to.

Edited by aehimself

Share this post


Link to post

Try next one method: 

 

public class Test
{

    public static void main(String[] args) throws JSONException
    {
        String data = "[{\"userName\": \"sandeep\",\"age\":30},{\"userName\": \"vivan\",\"age\":5}]  ";
        JSONArray jsonArr = new JSONArray(data);

        for (int i = 0; i < jsonArr.length(); i++)
        {
            JSONObject jsonObj = jsonArr.getJSONObject(i);

            System.out.println(jsonObj);
        }

    }
}

 

This way I used and it coincides with the opinion of people on Stackoverflow. 

Check next source: https://stackoverflow.com/questions/15609306/convert-string-to-json-array/source

 

Regards,

Jame Corbitt

Share this post


Link to post
9 hours ago, jamecorbitt said:

Try next one method: 

 


public class Test
{

    public static void main(String[] args) throws JSONException
    {
        String data = "[{\"userName\": \"sandeep\",\"age\":30},{\"userName\": \"vivan\",\"age\":5}]  ";
        JSONArray jsonArr = new JSONArray(data);

        for (int i = 0; i < jsonArr.length(); i++)
        {
            JSONObject jsonObj = jsonArr.getJSONObject(i);

            System.out.println(jsonObj);
        }

    }
}

 

This way I used and it coincides with the opinion of people on Stackoverflow. 

Check next source: https://stackoverflow.com/questions/15609306/convert-string-to-json-array/source

 

Regards,

Jame Corbitt

Quite odd to copy some code from an SO question that is in the wrong language. This code is Java. 

Edited by David Heffernan

Share this post


Link to post

Another method to do JSON to Object.

unit StructureTestTypes;

interface
uses
  REST.Json, System.SysUtils;

type
  TStructure = class(TObject) //   '{"RESULT":200, "IDLIST":[1,2,3,4,5]}'
  private
    FIDLIST: TArray<Integer>;
    FRESULT: integer;
  public
    constructor Create; virtual;
    destructor Destroy; override;
    property RESULT: integer read FRESULT write FRESULT;
    property IDLIST: TArray<Integer> read FIDLIST write FIDList;
  end;

implementation

{ TStructure }

constructor TStructure.Create;
begin
  SetLength(FIDLIST, 0);
end;

destructor TStructure.Destroy;
begin
  SetLength(FIDLIST, 0);
  inherited;
end;

end.


Test Program:
 

program JsonStructureTest;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils,
  REST.Json,
  StructureTestTypes in 'StructureTestTypes.pas';

var
  Test: TStructure;
begin
  Test := TJson.JsonToObject<TStructure>('{"RESULT":200, "IDLIST":[1,2,3,4,5]}']);
  try
    try
      Writeln('Result: ', Test.RESULT);
      Write('IDList:');
      for var i in Test.IDLIST
       do Write(' ', i );
      Writeln;
    except
      on E: Exception 
      do Writeln(E.ClassName, ': ', E.Message);
    end;
  finally
    Test.Free;
    Writeln;
    Write('Press Enter: ');
    Readln;
  end;
end.

 

  • Like 1

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

×