11

我正在寻找一个函数,它将以 JSON 字符串作为输入并使用换行符和缩进(制表符)对其进行格式化。

示例:我有输入行:

{"menu": {"header": "JSON viewer", "items": [{"id": "Delphi"},{"id": "Pascal", "label": "Nice tree format"}, null]}}

并希望以文本形式获得可读的结果:

{
   "menu":{
      "header":"JSON viewer",
      "items":[
       {
         "id":"Delphi"
       },
       {
         "id":"Pascal",
         "label":"Nice tree format"
       },
       null
      ]
   }
}

我找到了很多 PHP 和 C# 的示例,但不是 Delphi。有人可以帮助实现这样的功能吗?

更新 - 使用 SuperObject 的解决方案:

function FormatJson (InString: WideString): string; // Input string is "InString"
var
  Json : ISuperObject;
begin
  Json := TSuperObject.ParseString(PWideChar(InString), True);
  Result := Json.AsJson(true, false); //Here comes your result: pretty-print JSON
end;
4

5 回答 5

15

如果您不想使用任何外部库,并且您使用的是 delphi XE5 或更新版本,那么TJson.Format()该单元中有一个非常方便的功能REST.Json

uses json, REST.Json;

{ ... }    

function FormatJSON(json: String): String;
var
  tmpJson: TJsonObject;
begin
  tmpJson := TJSONObject.ParseJSONValue(json);
  Result := TJson.Format(tmpJson);

  FreeAndNil(tmpJson);
end;
于 2016-06-28T08:50:05.947 回答
7

您也可以使用我们开源单元的以下方法:SynCommons.pas

var json,new: RawUTF8;
begin
  json := '{"menu": {"header": "JSON viewer", "items": [{"id": "Delphi"},{"id": "Pascal", "label": "Nice tree format"}, null]}}';
  new := JSONReformat(json,jsonHumanReadable);
  ...

这里new将包含:

{
  "menu": {
    "header": "JSON viewer",
    "items": 
    [
      {
        "id": "Delphi"
      },
      {
        "id": "Pascal",
        "label": "Nice tree format"
      },
      null
    ]
  }
}

如果您使用以下jsonUnquotedPropName格式:

  new := JSONReformat(json,jsonUnquotedPropName);

您将获得以下扩展语法(类似于JavaScriptMongoDB shell 中使用的语法):

{
  menu: {
    header: "JSON viewer",
    items: 
    [
      {
        id: "Delphi"
      },
      {
        id: "Pascal",
        label: "Nice tree format"
      },
      null
    ]
  }
}

此语法被接受为我们开源框架的所有 JSON 函数的有效输入,作为默认 JSON 语法的替代。我们发现它非常有用,例如用于配置文件。

请注意,我们的JSONReformat()功能非常快。它可以在 1.4 秒内将来自CityLots的 190 MB 无法格式化的巨大 JSON 内容转换为 400 MB 的美化 JSON(预期和带有行字段)。SuperObject 仅能在 10 秒内读取它,并且仅使用 1.1 GB 来存储 190 MB 的内容。而且 DBXJSON 甚至无法加载数据:它消耗所有 32 位内存 - 在 Win64 (XE6) 下,需要 50 秒并使用 3 GB 的 RAM 来读取 190 MB 的 JSON。有关一些数字,请参阅本文

于 2014-08-22T20:29:38.553 回答
6

使用超级对象库,确保使用存储库文件中的最新版本,而不是 1.2.4 ZIP

然后你可以格式化你的 TSuperObject 对象.AsJSON(true)(“真”就可以了)。

[请注意,您无法控制 JSON 字段的显示顺序]

[并从字符串创建您的对象:var lJSON : ISuperObject; lJSON := SO(string);]

于 2013-08-29T12:48:13.233 回答
2

这有点老了,但如果有人对 Delphi 的本机 System.JSON 单元感兴趣,也可以这样做。示例使用 TMemo 和 TButton 来格式化 JSON

procedure TForm1.btnFormatJSONClick(Sender: TObject);
const
 DEF_INDENT = 2;
var
 JO : TJSONObject;
begin
 try
  JO := TJSONObject.ParseJSONValue(memoJSON.Text) as TJSONObject;
  memoJSON.Text := JO.Format(DEF_INDENT);
 except
  on E:Exception do
   begin
    MessageDlg('Error in JSON syntax', mtError, [mbOK], 0);
   end;
 end;
end;
于 2020-07-01T21:38:56.893 回答
1

如果您使用 Delphi XE 或更新版本,您可以使用delphi-xe-json

function PrettyPrint (aJSON : string) : string;
var
  jo : IJSONObject
begin
  jo := TJSON.NewObject(aJSON);
  result := jo.ToString(true);
end;
于 2013-08-29T13:56:50.070 回答