解析 JSON 字符串,其中包含 Delphi 中另一个 jsonstring 的字符串数组
Parsing a JSON string that contains an array of an array of a string of another jsonstring in Delphi
所以我正在与这个网络服务器通话,它返回给我一个 json 条目,如下所示:
{
"result": [
[],
["{\"success\": \"true\", \"Message\":\"User 1 has been deleted.\"}"]
]
}
{"result":[[],["{\"success\": \"true\", \"Message\":\"User 1 has been deleted.\"}"]]}
而且我很难从中得到一些东西。
看了一下,做了一个jsonobject,把result的值拉出来做成数组,然后把第一个数组的第二项拉出来做成另一个数组,然后把那个jsonstring拿过来转进入另一个 json 数组,然后取出值。
但出于某种原因,第一个 jsonarray 声称有两个值,这两个值都是空的。我敢肯定我的方法也有其他错误。
我可以帮忙熨一下吗?
procedure DeleteUser;
var
aJSON, aResult : String;
aJsonResponse : TJsonObject;
aResultArrayA : TJsonArray;
aResultArrayB : TJsonArray;
aResultArrayC : TJsonArray;
aParsed : TJsonValue;
i : Integer;
Begin
aresult := '{"result":[[],["{\"success\": \"true\", \"Message\":\"User 1 has been deleted.\"}"]]}';
aJsonResponse := TJsonObject.ParseJSONValue(aResult) as TJsonObject;
if not (aJsonResponse is TJsonObject) then
raise Exception.Create('InvalidResponse');
aResultArrayA := aJsonResponse.getValue('result') as TJsonArray;
if aResultArrayA.Count <= 0 then //is 2
raise Exception.Create('InvalidResponse');
aJSON := aResultArrayA.Items[0].Value; // is ''
aJSON := aResultArrayA.Items[1].Value; // is ''
aResultArrayB := aResultArrayA.Items[0] as TJSONArray;
if aResultArrayB.Count <= 0 then // is 0
raise Exception.Create('InvalidResponse'); //raises here
aJSON := aResultArrayB.Items[0].Value;
aJSON := aResultArrayB.Items[1].Value;
aResultArrayC := TJSONObject.ParseJSONValue(aResultArrayB.Items[1].Value) as TJSONArray;
for aParsed in aResultArrayC do begin
aJson := aJson + aParsed.GetValue<string>('success') + ' ';
aJson := aJson + aParsed.GetValue<string>('message') + ' ';
end;
end;
谢谢大家
我真的认为使用 JSON 的最佳方式是序列化和反序列化。是的,有些情况下使用解析会更好,但是看看这个:
uses ...,Rest.Json;
TMyArray = ARRAY of ARRAY of string;
//class for deserialization outer JSON object
TMyParse = CLASS
private
FResult:TMyArray;
procedure SetResult(const Value: TMyArray);
public
property result:TMyArray read FResult write SetResult;
END;
//class for deserialization inner JSON object
TMyInnerParse = class
private
FSuccess:Boolean;
FMessage:string;
procedure SetMessage(const Value: String);
procedure SetSuccess(const Value: Boolean);
public
property success:Boolean read FSuccess write SetSuccess;
property message:String read FMessage write SetMessage;
end;
procedure DeleteUser;
var
OuterObj: TMyParse;
InnerObj: TMyInnerParse;
aResult: String;
i,j: Integer;
Begin
aResult := '{"result":[[],["{\"success\": \"true\", \"Message\":\"User 1 has been deleted.\"}"]]}';
try
OuterObj := TJson.JsonToObject<TMyParse>(aResult);
if Length(OuterObj.result) > 0 then
for i := 0 to Length(OuterObj.result) - 1 do
if length(OuterObj.result[i]) > 0 then
for j := 0 to Length(OuterObj.result[i]) - 1 do
begin
try
InnerObj := TJson.JsonToObject<TMyInnerParse>(OuterObj.result[i][j]);
//Do your work with result, that in InnerObj now
finally
if assigned(InnerObj) then
FreeAndNil(InnerObj);
end;
end;
finally
if assigned(OuterObj) then
FreeAndNil(OuterObj);
end;
end;
procedure TMyParse.SetResult(const Value: TMyArray);
begin
FResult := value;
end;
procedure TMyInnerParse.SetMessage(const Value: String);
begin
FMessage := value;
end;
procedure TMyInnerParse.SetSuccess(const Value: Boolean);
begin
FSuccess := value;
end;
For
这段代码中的循环很糟糕,但它是展示如何解决问题的最快方式。它正在运行。
我不知道第一个空数组中可以包含什么信息,这可能是出现异常的原因。将此代码视为工作示例,而不是完整的解决方案,因为缺少信息。
已在 Delphi 10.1 上测试:
P.S。在这种情况下使用数组是非常古老的编码方式。但是前段时间我遇到了 serializing/deserializing TList 和 TObjectList 的问题。我会尝试使用它们并将 return 与结果。
P.P.S。它试图使用 TList,但我的尝试失败了。也许有人可以在上面的代码中描述如何实现它。
在 system.JSON 中找到了这些功能,它们为我点击了。
/// <summary>Finds a JSON value and returns reference to it. </summary>
/// <remarks> Raises an exception when a JSON value could not be found. </remarks>
property P[const APath: string]: TJSONValue read GetValueP;{ default;}
property A[const AIndex: Integer]: TJSONValue read GetValueA;
var
aSuccess, aMessage : String
aJSON : TJSONObject;
begin
var aJSON:= TJSONObject.ParseJSONValue('{"result":[[],["{\"success\": \"true\", \"Message\":\"User has been deleted.\"}"]]}');
aSuccess := TJSONObject.ParseJSONValue(aJSON.P['result'].A[1].A[0].AsType<String>).P['success'].AsType<String>;
aMessage := TJSONObject.ParseJSONValue(aJSON.P['result'].A[1].A[0].AsType<String>).P['Message'].AsType<String>;
end;
注意这里需要异常处理,所有这些函数如果找不到指定的属性.
都会抛出异常
所以我正在与这个网络服务器通话,它返回给我一个 json 条目,如下所示:
{
"result": [
[],
["{\"success\": \"true\", \"Message\":\"User 1 has been deleted.\"}"]
]
}
{"result":[[],["{\"success\": \"true\", \"Message\":\"User 1 has been deleted.\"}"]]}
而且我很难从中得到一些东西。 看了一下,做了一个jsonobject,把result的值拉出来做成数组,然后把第一个数组的第二项拉出来做成另一个数组,然后把那个jsonstring拿过来转进入另一个 json 数组,然后取出值。 但出于某种原因,第一个 jsonarray 声称有两个值,这两个值都是空的。我敢肯定我的方法也有其他错误。
我可以帮忙熨一下吗?
procedure DeleteUser;
var
aJSON, aResult : String;
aJsonResponse : TJsonObject;
aResultArrayA : TJsonArray;
aResultArrayB : TJsonArray;
aResultArrayC : TJsonArray;
aParsed : TJsonValue;
i : Integer;
Begin
aresult := '{"result":[[],["{\"success\": \"true\", \"Message\":\"User 1 has been deleted.\"}"]]}';
aJsonResponse := TJsonObject.ParseJSONValue(aResult) as TJsonObject;
if not (aJsonResponse is TJsonObject) then
raise Exception.Create('InvalidResponse');
aResultArrayA := aJsonResponse.getValue('result') as TJsonArray;
if aResultArrayA.Count <= 0 then //is 2
raise Exception.Create('InvalidResponse');
aJSON := aResultArrayA.Items[0].Value; // is ''
aJSON := aResultArrayA.Items[1].Value; // is ''
aResultArrayB := aResultArrayA.Items[0] as TJSONArray;
if aResultArrayB.Count <= 0 then // is 0
raise Exception.Create('InvalidResponse'); //raises here
aJSON := aResultArrayB.Items[0].Value;
aJSON := aResultArrayB.Items[1].Value;
aResultArrayC := TJSONObject.ParseJSONValue(aResultArrayB.Items[1].Value) as TJSONArray;
for aParsed in aResultArrayC do begin
aJson := aJson + aParsed.GetValue<string>('success') + ' ';
aJson := aJson + aParsed.GetValue<string>('message') + ' ';
end;
end;
谢谢大家
我真的认为使用 JSON 的最佳方式是序列化和反序列化。是的,有些情况下使用解析会更好,但是看看这个:
uses ...,Rest.Json;
TMyArray = ARRAY of ARRAY of string;
//class for deserialization outer JSON object
TMyParse = CLASS
private
FResult:TMyArray;
procedure SetResult(const Value: TMyArray);
public
property result:TMyArray read FResult write SetResult;
END;
//class for deserialization inner JSON object
TMyInnerParse = class
private
FSuccess:Boolean;
FMessage:string;
procedure SetMessage(const Value: String);
procedure SetSuccess(const Value: Boolean);
public
property success:Boolean read FSuccess write SetSuccess;
property message:String read FMessage write SetMessage;
end;
procedure DeleteUser;
var
OuterObj: TMyParse;
InnerObj: TMyInnerParse;
aResult: String;
i,j: Integer;
Begin
aResult := '{"result":[[],["{\"success\": \"true\", \"Message\":\"User 1 has been deleted.\"}"]]}';
try
OuterObj := TJson.JsonToObject<TMyParse>(aResult);
if Length(OuterObj.result) > 0 then
for i := 0 to Length(OuterObj.result) - 1 do
if length(OuterObj.result[i]) > 0 then
for j := 0 to Length(OuterObj.result[i]) - 1 do
begin
try
InnerObj := TJson.JsonToObject<TMyInnerParse>(OuterObj.result[i][j]);
//Do your work with result, that in InnerObj now
finally
if assigned(InnerObj) then
FreeAndNil(InnerObj);
end;
end;
finally
if assigned(OuterObj) then
FreeAndNil(OuterObj);
end;
end;
procedure TMyParse.SetResult(const Value: TMyArray);
begin
FResult := value;
end;
procedure TMyInnerParse.SetMessage(const Value: String);
begin
FMessage := value;
end;
procedure TMyInnerParse.SetSuccess(const Value: Boolean);
begin
FSuccess := value;
end;
For
这段代码中的循环很糟糕,但它是展示如何解决问题的最快方式。它正在运行。
我不知道第一个空数组中可以包含什么信息,这可能是出现异常的原因。将此代码视为工作示例,而不是完整的解决方案,因为缺少信息。
已在 Delphi 10.1 上测试:
P.S。在这种情况下使用数组是非常古老的编码方式。但是前段时间我遇到了 serializing/deserializing TList 和 TObjectList 的问题。我会尝试使用它们并将 return 与结果。
P.P.S。它试图使用 TList,但我的尝试失败了。也许有人可以在上面的代码中描述如何实现它。
在 system.JSON 中找到了这些功能,它们为我点击了。
/// <summary>Finds a JSON value and returns reference to it. </summary>
/// <remarks> Raises an exception when a JSON value could not be found. </remarks>
property P[const APath: string]: TJSONValue read GetValueP;{ default;}
property A[const AIndex: Integer]: TJSONValue read GetValueA;
var
aSuccess, aMessage : String
aJSON : TJSONObject;
begin
var aJSON:= TJSONObject.ParseJSONValue('{"result":[[],["{\"success\": \"true\", \"Message\":\"User has been deleted.\"}"]]}');
aSuccess := TJSONObject.ParseJSONValue(aJSON.P['result'].A[1].A[0].AsType<String>).P['success'].AsType<String>;
aMessage := TJSONObject.ParseJSONValue(aJSON.P['result'].A[1].A[0].AsType<String>).P['Message'].AsType<String>;
end;
注意这里需要异常处理,所有这些函数如果找不到指定的属性.
都会抛出异常