Luiz Alves
Luiz Alves

Reputation: 2645

How to parse a json string response using Delphi

I have a rest server returning the next json string:

response:='{"result":["[{\"email\":\"[email protected]\",\"regid\":\"12312312312312312313213w\"},{\"email\":\"[email protected]\",\"regid\":\"AAAAAAA\"}]"]}';

I´d like to parse the response to get a list of all email and regid items.

I have tried the next code but I am getting an AV at (TJSONPair(LItem).JsonString.Value='email')

Any help will be appreciated.

Thanks in advance, Luiz

var
  LResult:TJSONArray;
  LJsonresponse:TJSONObject;
  i:integer;
  LItem,jv:TJsonValue;
  email,regid:string;

      LJsonresponse:=TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(response),0) as TJSONObject;
      LResult:=(LJsonresponse.GetValue('result') as TJSONArray);
      jv:=TJSONArray(LResult.Get(0));
      for LItem in TJSONArray(jv) do begin
         if (TJSONPair(LItem).JsonString.Value='email') then begin
           email:=TJSONPair(LItem).JsonValue.Value;
         end;
         if (TJSONPair(LItem).JsonString.Value='regid') then begin
           regid:=TJSONPair(LItem).JsonValue.Value;
         end;
      end;

Upvotes: 10

Views: 39362

Answers (1)

David Heffernan
David Heffernan

Reputation: 612993

Your problems start here:

jv := TJSONArray(LResult.Get(0));

The problem is that LResult.Get(0) does not return an instance of TJSONArray. In fact it returns an instance of TJSONString. That string has value:

'[{"email":"[email protected]","regid":"12312312312312312313213w"},{"email":"[email protected]","regid":"AAAAAAA"}]'

It looks like you are going to need to parse this string as JSON to extract what you need. Here is some gnarly code that does that. Please excuse its quality because I have no experience at all with the Delphi JSON parser.

{$APPTYPE CONSOLE}

uses
  SysUtils, JSON;

const
  response =
    '{"result":["[{\"email\":\"[email protected]\",\"regid\":\"12312312312312312313213w\"},'+
    '{\"email\":\"[email protected]\",\"regid\":\"AAAAAAA\"}]"]}';

procedure Main;
var
  LResult: TJSONArray;
  LJsonResponse: TJSONObject;
  ja: TJSONArray;
  jv: TJSONValue;
begin
  LJsonResponse := TJSONObject.ParseJSONValue(response) as TJSONObject;
  LResult := LJsonResponse.GetValue('result') as TJSONArray;
  ja := TJSONObject.ParseJSONValue(LResult.Items[0].Value) as TJSONArray;
  for jv in ja do begin
    Writeln(jv.GetValue<string>('email'));
    Writeln(jv.GetValue<string>('regid'));
  end;
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

The big lesson here is to stop using unchecked type casts. Using such casts is asking for trouble. When your data does not match your code, you get unhelpful error messages.

Upvotes: 16

Related Questions