在Delphi中解析包含另一个jsonstring的字符串数组的JSON字符串

在Delphi中解析包含另一个jsonstring的字符串数组的JSON字符串,json,parsing,delphi,delphi-10.3-rio,Json,Parsing,Delphi,Delphi 10.3 Rio,我正在和这个Web服务器交谈,它会返回一个json条目,如下所示: { "result": [ [], ["{\"success\": \"true\", \"Message\":\"User 1 has been deleted.\"}"] ] } {"result":[[],["{\"success\": \&

我正在和这个Web服务器交谈,它会返回一个json条目,如下所示:

{
 "result": [
  [],
  ["{\"success\": \"true\", \"Message\":\"User 1 has been deleted.\"}"]
 ]
}

{"result":[[],["{\"success\": \"true\", \"Message\":\"User 1 has been deleted.\"}"]]}
我很难从中解脱出来。 查看它,我创建了一个jsonobject,提取result的值并将其生成一个数组,然后将第一个数组的第二个条目作为另一个数组提取,然后将该jsonstring转换为另一个jsonarray,然后取出值。 但出于某种原因,第一个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;
程序删除用户;
变量
aJSON,aResult:String;
aJsonResponse:TJsonObject;
阿雷苏特拉亚:TJsonArray;
aResultArrayB:TJsonArray;
aresultarray:TJsonArray;
隔离:TJsonValue;
i:整数;
开始
结果:='{“结果”:[[],[“{\'success\':\'true\',\'Message\':\'用户1已被删除。\“}”]};
aJsonResponse:=TJsonObject.ParseJSONValue(aResult)作为TJsonObject;
如果不是(aJsonResponse是TJsonObject),则
引发异常。创建('InvalidResponse');
aResultArrayA:=aJsonResponse.getValue('result')作为TJsonArray;

如果aResultArrayA.Count我真的认为使用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;
使用…,Rest.Json;
TMyArray=字符串数组的数组;
//用于反序列化外部JSON对象的类
TMyParse=CLASS
私有的
FResult:TMyArray;
程序设置结果(常数值:TMyArray);
公众的
属性结果:TMyArray read FResult write SetResult;
结束;
//用于反序列化内部JSON对象的类
TMYinerParse=类
私有的
FSuccess:布尔值;
FMessage:字符串;
过程设置消息(常量值:字符串);
过程SetSuccess(常量值:布尔值);
公众的
属性成功:布尔读取fsucces写入SetSuccess;
属性消息:字符串读取FMessage写入SetMessage;
结束;
程序删除用户;
变量
OuterObj:TMyParse;
InnerObj:TMyInnerParse;
结果:字符串;
i、 j:整数;
开始
结果:='{“结果”:[[],[“{\'success\':\'true\',\'Message\':\'用户1已被删除。\“}”]};
尝试
OuterObj:=TJson.JsonToObject(aResult);
如果长度(OuterObj.result)>0,则
对于i:=0到长度(OuterObj.result)-1 do
如果长度(OuterObj.result[i])>0,则
对于j:=0到长度(OuterObj.result[i])-1 do
开始
尝试
InnerObj:=TJson.JsonToObject(OuterObj.result[i][j]);
//使用InnerObj中的结果执行您的工作
最后
如果已分配(InnerObj),则
FreeAndNil(innernobj);
结束;
结束;
最后
如果已分配(OuterObj),则
FreeAndNil(OuterObj);
结束;
结束;
程序TMyParse.SetResult(常量值:TMyArray);
开始
FResult:=值;
结束;
过程TMYinerParse.SetMessage(常量值:字符串);
开始
FMessage:=值;
结束;
过程TMyInnerParse.SetSuccess(常量值:布尔值);
开始
FSuccess:=值;
结束;
For
此代码中的循环非常糟糕,但这是展示如何解决问题的最快方式。它正在工作

我不知道第一个空数组中可以包含哪些信息,这可能是出现异常的原因。将此代码视为工作示例,而不是完整的解决方案,因为缺少信息

在Delphi 10.1上进行了测试:

在这种情况下,使用数组是非常古老的编码方式。但不久前,我遇到了序列化/反序列化TList和TObjectList的问题。我将尝试使用它们,并返回结果


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值并返回对该值的引用。
///找不到JSON值时引发异常。
属性P[const-APath:string]:TJSONValue读取GetValueP;{default;}
属性A[const AIndex:Integer]:TJSONValue读取GetValueA;
变量
a成功,a消息:String
aJSON:TJSONObject;
开始
var aJSON:=TJSONObject.ParseJSONValue(“{”结果“:[[],[“{\”成功“:\”真“,\”消息\“:\”用户已被删除。\“}”]}”);
AsAccess:=TJSONObject.ParseJSONValue(aJSON.P['result'].A[1].A[0].AsType).P['success'].AsType;
aMessage:=TJSONObject.ParseJSONValue(aJSON.P['result'].A[1].A[0].AsType).P['Message'].AsType;
结束;

请注意,这需要异常处理,如果所有这些函数找不到指定的属性,它们都将抛出异常。

谢谢您,工作代码为+1,但我最终选择了找到的答案。