delphi parse jsonarray with System.JSON
10,486
Solution 1
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.
Solution 2
Just as an alternative to the solution provided but using mORMot:
{$APPTYPE CONSOLE}
uses
SynCommons;
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" } ] } }';
var Data , CurrentConditionArray : TDocVariantData;
Current_Condition , Json : Variant;
begin
Json := _Json(Text);
// Alternative 1
Current_Condition := Json.data.current_condition._(0);
Assert( Current_Condition.observation_time = '04:10 AM' );
// Alternative 2 slightly faster
Data := TDocVariantData(Json).O['data']^;
CurrentConditionArray := Data.A['current_condition']^;
Current_Condition := CurrentConditionArray.Values[0];
Assert( TDocVariantData(Current_Condition).Value['precipMM'] = '0.0' );
end.
This should work from Delphi 7 to 10.4. Please, find further details and alternatives in the amazing documentation
Author by
Drdead
Updated on June 05, 2022Comments
-
Drdead almost 2 years
Using Delphi XE8's
System.JSON
, I cannot parse a jsonarraySample 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));
-
Drdead over 8 yearserror in function TJSONArray.GetCount: Integer; begin if (FElements = nil) or (FElements.Count = 0) then Exit(0); Result := FElements.Count; end; (FElements = nil)
-
Drdead over 8 yearsDone JSONObject2:=JSONObject.GetValue('data') as TJSONObject; arrayjson:=JSONObject2.GetValue('current_condition') as TJSONArray; currcond := arrayjson.Items[0] as TJSONObject; // parse currcond/// memores1.Add((currcond.GetValue('cloudcover').Value));
-