Search code examples
jsondelphiparsingsystem.json

delphi parse jsonarray with System.JSON


Using Delphi XE8's System.JSON, I cannot parse a jsonarray

Sample Json:

{
    "data":{
        "current_condition":[
            {
                "cloudcover":"0",
                "FeelsLikeC":"-9",
                "FeelsLikeF":"15",
                "humidity":"93",
                "observation_time":"04:10 AM",
                "precipMM":"0.0",
                "pressure":"1007",
                "temp_C":"-6",
                "temp_F":"21",
                "visibility":"10",
                "weatherCode":"113",
                "weatherDesc":[
                    
                ],
                "weatherIconUrl":[
                    
                ],
                "winddir16Point":"SE",
                "winddirDegree":"130",
                "windspeedKmph":"7",
                "windspeedMiles":"4"
            }
        ]
    }
}

using the code:

memores: TStringList;
currcond: TJSONObject;

memores2.Text := http.Get ('url');
JSONObject := TJSONObject.ParseJSONValue(memores2.Text) as TJSONObject;
Memores1.add('current_condition');
JSONObject2 := JSONObject.GetValue('data')   as TJSONObject;
arrayjson := JSONObject2.ParseJSONValue('current_condition')  as TJSONArray;
currcond := arrayjson.Items[0] as TJSONObject;
memores1.Add((currcond.GetValue('cloudcover').Value));

Solution

  • arrayjson:=JSONObject2.ParseJSONValue('current_condition')  as TJSONArray;
    

    This attempts to parse the text

    current_condition
    

    as though it were JSON. It is not. Hence arrayjson is nil, and hence the resulting runtime error. Replace that line of code with:

    arrayjson := JSONObject2.GetValue('current_condition') as TJSONArray;
    

    For example, this program:

    {$APPTYPE CONSOLE}
    
    uses
      System.SysUtils,
      System.JSON;
    
    const
      Text =
        '{ "data":{ "current_condition":[ { "cloudcover":"0", "FeelsLikeC":"-9", "FeelsLikeF":"15", "humidity":"93", ' +
        '"observation_time":"04:10 AM", "precipMM":"0.0", "pressure":"1007", "temp_C":"-6", "temp_F":"21", "visibility":"10", ' +
        '"weatherCode":"113", "weatherDesc":[], "weatherIconUrl":[], "winddir16Point":"SE", "winddirDegree":"130", "windspeedKmph":"7", "windspeedMiles":"4" } ] } }';
    
    procedure Main;
    var
      JSONObject, JSONObject2, currcond: TJSONObject;
      arrayjson: TJSONArray;
    begin
      JSONObject := TJSONObject.ParseJSONValue(Text) as TJSONObject;
      JSONObject2 := JSONObject.GetValue('data') as TJSONObject;
      arrayjson := JSONObject2.GetValue('current_condition') as TJSONArray;
      currcond := arrayjson.Items[0] as TJSONObject;
      Writeln(currcond.GetValue('observation_time').Value);
    end;
    
    begin
      try
        Main;
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
      Readln;
    end.
    

    outputs

    04:10 AM
    

    In the simple code above, I've not made any attempt to add error checking. You should do so.