Delphi:将 JSON 数组添加到 JSON 对象

Joh*_*han 2 delphi json delphi-2010

我正在使用 Indy 调用第 3 方 API

\n
var loRespJson: TMemoryStream;\nIdHTTP1.GET(lsURL, loRespJson)\n
Run Code Online (Sandbox Code Playgroud)\n

它返回一个 JSON 数组:

\n
var loRespJson: TMemoryStream;\nIdHTTP1.GET(lsURL, loRespJson)\n
Run Code Online (Sandbox Code Playgroud)\n

反过来,我的函数创建一个新的 JSON 对象,添加附加信息和响应,并将其返回给调用程序。期望的结果:

\n
[\n    {\n        "Active": "1",\n        "SourceId": "215",\n        "SourceName": "MyVal1"\n    },\n    {\n        "Active": "1",\n        "SourceId": "383",\n        "SourceName": "MyVal2"\n    }\n]\n
Run Code Online (Sandbox Code Playgroud)\n

我怎样才能实现上述目标?如果我使用以下内容添加,它会在数组周围创建“”(引号),这在解析 JSON 时是一个大问题:

\n
loJSon.AddPair(TJSONPair.Create(\'responseCode\', IntToStr(idHttp1.ResponseCode)));\nloJSon.AddPair(TJSONPair.Create(\'companyNo\', CompanyNo));\n\nif idHttp1.ResponseCode = 200 then\nbegin\n  lsRespMsg := StreamToString(loRespJSon);\n  liSuper := SO(lsRespMsg);\n  loJSon.AddPair(TJSONPair.Create(\'responseMessage\', liSuper.AsJSon()));\n  \xe2\x80\xa6\n
Run Code Online (Sandbox Code Playgroud)\n

我也尝试过循环遍历 JSON 数组,但该选项在每个数组项周围添加了“”

\n
{ create an json-array }\nloJSA := TJsonArray.Create();\n{ add array to object }\nloJSP := TJSONPair.Create(\'responseMessage\', loJSA);\nloJSon.AddPair(loJSP);\n\nif liSuper.IsType(stArray) then\nbegin\n  for i := 0 to liSuper.AsArray.Length - 1 do\n  begin\n    loSubscription := liSuper.AsArray[i];\n    loJSA.Add(loSubscription.AsJSon());\n  end;\nend;\n
Run Code Online (Sandbox Code Playgroud)\n

任何帮助将不胜感激!谢谢。

\n

Pet*_*olf 5

看来您在尝试构建 JSON 新响应时使用了System.JSONloJSon: TJSONObject单元。然后,您解析了使用SuperObject库中的函数收到的响应正文,该库与 System.JSON 不太兼容。TIdHTTPSO()

到目前为止,该方法很好,但您应该坚持使用单个库。解析响应后,您添加了一对 TJSONObject ,liSuper.AsJSon()其值是一个字符串。这解释了数组周围的双引号。

仅使用 System.JSON 的正确解决方案可能如下所示:

uses
  System.SysUtils, System.JSON;

const
  ResponseMessageStr = '[{"Active":"1","SourceId":"215","SourceName":"MyVal1"},{"Active":"1","SourceId":"383","SourceName":"MyVal2"}]';
var
  ResponseJSON: TJSONObject;
begin
  ResponseJSON := TJSONObject.Create;
  try
    ResponseJSON.AddPair('responseCode', '200');
    ResponseJSON.AddPair('companyNo', '0268895');
    ResponseJSON.AddPair('responseMessage', TJSONObject.ParseJSONValue(ResponseMessageStr));
    Writeln(ResponseJSON.Format());
  finally
    ResponseJSON.Free;
  end;
end.
Run Code Online (Sandbox Code Playgroud)

在上面的代码片段中,我用来TJSONObject.ParseJSONValue解析响应消息并将其附加到生成的 JSON 对象中。尽管我的响应消息存储在字符串常量中,但您可以轻松地调整该解决方案以与TMemoryStreamor 一起使用TIdHTTP。检查 的所有不变量TJSONObject.ParseJSONValue

该片段产生输出:

uses
  System.SysUtils, System.JSON;

const
  ResponseMessageStr = '[{"Active":"1","SourceId":"215","SourceName":"MyVal1"},{"Active":"1","SourceId":"383","SourceName":"MyVal2"}]';
var
  ResponseJSON: TJSONObject;
begin
  ResponseJSON := TJSONObject.Create;
  try
    ResponseJSON.AddPair('responseCode', '200');
    ResponseJSON.AddPair('companyNo', '0268895');
    ResponseJSON.AddPair('responseMessage', TJSONObject.ParseJSONValue(ResponseMessageStr));
    Writeln(ResponseJSON.Format());
  finally
    ResponseJSON.Free;
  end;
end.
Run Code Online (Sandbox Code Playgroud)

另请注意,TJSONObject.AddPair为了方便起见,它具有多个不变量。另一点是我使用Format方法来漂亮地打印 JSON 对象的内容,但您可能应该ToJSON在生产中使用。

使用 SuperObject 库的解决方案可产生等效结果:

uses
  System.SysUtils, SuperObject;

const
  ResponseMessageStr = '[{"Active":"1","SourceId":"215","SourceName":"MyVal1"},{"Active":"1","SourceId":"383","SourceName":"MyVal2"}]';
var
  ResponseJSON: ISuperObject;
begin
  ResponseJSON := TSuperObject.Create;
  ResponseJSON.I['responseCode'] := 200;
  ResponseJSON.S['responseCode'] := '0268895';
  ResponseJSON.O['responseMessage'] := SO(ResponseMessageStr);
  Writeln(ResponseJSON.AsJSon(True));
  Readln;
end.
Run Code Online (Sandbox Code Playgroud)