如何解决Delphi解析JSON
我需要读取fuelTanks
值。之前的一切都归我所有/实际上还有更多内容,但是我不知道如何阅读fuelTanks
字段。
我当前的代码:
procedure TMain.JsonAktStav;
var
JSonObject: TJSonObject;
data: TJSONArray;
JSonValue: TJSonValue;
//*** bJSon is the TByteStream from the previous procedure ***
idx: integer;
begin
JSonObject := TJSonObject.Create;
JSonValue := JSonObject.ParseJSONValue(bJSON.Bytes,bJSON.Size) as TJSONObject;
JSonValue := (JSonValue as TJSONObject).Get('response').JSonValue;
JSonValue := (JSonValue as TJSONObject).Get('data').JSonValue;
data := JSonValue as TJSONArray;
for idx := 0 to data.Size - 1 do
begin
if (JSonValue is TJSONArray) then
vehicleid := ((JSonValue as TJSONArray).Items[idx] as TJSonObject).Get('vehicleid').JSonValue.Value;
end;
JSonObject.Free;
bJSON.Free;
end;
TIdHTTP
将返回JSON响应,如下所示:
{
"response": {
"actionName": "getActualStates","code": 200,"data": [
{
"vehicleid": 4500,"temperatures": [],"fuelTanks": [
{
"fuelTankNumber": 1,"status": 247
},{
"fuelTankNumber": 2,"status": 65
}
]
},{
"vehicleid": 4751,"status": 462
},"status": 380
}
]
}
]
}
}
我无法阅读"fuelTankNumber"
和"status"
。
解决方法
fuelTanks
是一个对象数组,您已经知道如何访问作为数组和对象的子字段,因此只需要进一步扩展代码以更深入地迭代JSON结构即可,例如:>
procedure TMain.JsonAktStav;
var
JSonValue: TJSonValue;
data,fuelTanks: TJSONArray;
vehicle,fuelTank: TJSonObject;
idx,idx2: integer;
vehicleid,fuelTankNumber,status: integer;
begin
try
//*** bJSon is the TByteStream from the previous procedure ***
JSonValue := JSonObject.ParseJSONValue(bJSON.Bytes,bJSON.Size);
if JSonValue <> nil then
try
JSonObject := JSonValue as TJSONObject;
JSonObject := JSonObject.GetValue<TJSONObject>('response');
data := JSonObject.GetValue<TJSONArray>('data');
for idx := 0 to data.Size - 1 do
begin
vehicle := data.Items[idx] as TJSONObject;
vehicleid := vehicle.GetValue<Integer>('vehicleid');
// use vehicleid as needed...
fuelTanks := vehicle.GetValue<TJSONArray>('fuelTanks');
for idx2 := 0 to fuelTanks.Size - 1 do
begin
fuelTank := fuelTanks.Items[idx2] as TJSONObject;
fuelTankNumber := fuelTank.GetValue<Integer>('fuelTankNumber');
status := fuelTank.GetValue<Integer>('status');
// use fuelTankNumber and status as needed...
end;
end;
finally
JSonValue.Free;
end;
finally
bJSON.Free;
end;
end;
,
正如我之前所说,我认为使用JSON的最佳方法是序列化和反序列化。
因此,首先,您必须描述代表json的对象(我已将其制作成单位):
unit Unit3;
interface
TYPE
TMyDoubleArray = Array OF double;
TMyFuelObject = CLASS(TObject)
PRIVATE
FFuelTankNumber:integer;
FStatus:integer;
procedure SetFuelTankNumber(const Value: integer);
procedure SetStatus(const Value: Integer);
PUBLIC
property fuelTankNumber:integer read FFuelTankNumber write SetFuelTankNumber;
property status:Integer read FStatus WRITE SetStatus;
END;
TMyFuelArray = ARRAY OF TMyFuelObject;
TMyAnotherOneInnerObject = CLASS(TObject)
private
FVehicleId:Integer;
FTemperatures:TMyDoubleArray;
FFuelTanks:TMyFuelArray;
procedure SetFuelTanks(const Value: TMyFuelArray);
procedure SetTemperatures(const Value: TMyDoubleArray);
procedure SetVehicleId(const Value: integer);
PUBLIC
property vehicleid:integer read FVehicleId WRITE SetVehicleId;
property temperatures:TMyDoubleArray read FTemperatures write SetTemperatures; //Is it double?
property fuelTanks:TMyFuelArray read FFuelTanks write SetFuelTanks;
END;
TMyInnerArray = ARRAY of TMyAnotherOneInnerObject;
TMyInnerObject = CLASS(TObject)
PRIVATE
FActionName:String;
FCode:SmallInt;
FData:TMyInnerArray;
procedure SetActionName(const Value: String);
procedure SetCode(const Value: SmallInt);
procedure SetData(const Value: TMyInnerArray);
PUBLIC
property actionName:String read FActionName write SetActionName;
PROPERTY code:SmallInt read FCode write SetCode;
PROPERTY data:TMyInnerArray read FData write SetData;
END;
TMyObject = CLASS(TObject)
PRIVATE
FResponse:TMyInnerObject;
procedure SetResponse(const Value: TMyInnerObject);
PUBLIC
PROPERTY response:TMyInnerObject READ FResponse WRITE SetResponse;
END;
implementation
{ TMyObject }
procedure TMyObject.SetResponse(const Value: TMyInnerObject);
begin
FResponse := Value;
end;
{ TMyInnerObject }
procedure TMyInnerObject.SetActionName(const Value: String);
begin
FActionName := Value;
end;
procedure TMyInnerObject.SetCode(const Value: SmallInt);
begin
FCode := Value;
end;
procedure TMyInnerObject.SetData(const Value: TMyInnerArray);
begin
FData := Value;
end;
{ TMyAnotherOneInnerObject }
procedure TMyAnotherOneInnerObject.SetFuelTanks(const Value: TMyFuelArray);
begin
FFuelTanks := Value;
end;
procedure TMyAnotherOneInnerObject.SetTemperatures(const Value: TMyDoubleArray);
begin
FTemperatures := Value;
end;
procedure TMyAnotherOneInnerObject.SetVehicleId(const Value: integer);
begin
FVehicleId := Value;
end;
{ TMyFuelObject }
procedure TMyFuelObject.SetFuelTankNumber(const Value: integer);
begin
FFuelTankNumber := Value;
end;
procedure TMyFuelObject.SetStatus(const Value: Integer);
begin
FStatus := Value;
end;
end.
是的,有很多代码。但是,如果将来尝试使用此信息,则比解析json中的每个字段都容易。
然后您必须解析它。我已经将您的JSON放入表单的Memo并实现了此OnButtonClick事件:
uses ... REST.Json,Unit3;
...
procedure TForm2.Button1Click(Sender: TObject);
var json:string;
myObject:TMyObject;
begin
json := Memo1.Text;
try
myObject := TJson.JsonToObject<TMyObject>(json);
//do with myObject everything you want
finally
FreeAndNil(myObject);
end;
end;
然后我得到了:
要获取值,请尝试以下代码:
if length(myObject.response.data) > 0 then
for i := 0 to length(myObject.response.data) - 1 do
with myObject.response.data[i] do
if length(FuelTanks) > 0 then
for j := 0 to length(FuelTanks) - 1 do
ShowMessage(FuelTanks[j].FuelTankNumber.ToString); // or inttostr(FuelTanks[j].FuelTankNumber)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。