简体   繁体   English

如何在 Delphi 中漂亮地打印 JSON?

[英]How do I pretty-print JSON in Delphi?

I am looking for a function that will take a string of JSON as input and format it with line breaks and indentations (tabs).我正在寻找一个函数,它将以 JSON 字符串作为输入并使用换行符和缩进(制表符)对其进行格式化。

Example: I have input line:示例:我有输入行:

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

And want to get a readable result as text:并希望以文本形式获得可读的结果:

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

I found a lot of examples for PHP and C#, but not for Delphi.我找到了很多 PHP 和 C# 的示例,但不是 Delphi。 Could someone help with such a function?有人可以帮助实现这样的功能吗?

Update - Solution with SuperObject:更新 - 使用 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;

If you do not want to use any external library, and you're using a delphi XE5 or newer, there is a very handy TJson.Format() function in the REST.Json unit.如果您不想使用任何外部库,并且您使用的是 delphi XE5 或更新版本,那么REST.Json单元中有一个非常方便的TJson.Format()函数。

uses json, REST.Json;

{ ... }    

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

  FreeAndNil(tmpJson);
end;

You may also use the following methods of our Open Source SynCommons.pas unit:您还可以使用我们开源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);
  ...

Here new will contain:这里new将包含:

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

If you use the jsonUnquotedPropName format:如果您使用jsonUnquotedPropName格式:

  new := JSONReformat(json,jsonUnquotedPropName);

you will get the following extended syntax (similar to the one used in JavaScript or MongoDB shell):您将获得以下扩展语法(类似于JavaScriptMongoDB shell 中使用的语法):

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

This syntax is accepted as valid input for all the JSON functions of our Open Source framework, as alternative to the default JSON syntax.此语法被接受为我们开源框架的所有 JSON 函数的有效输入,作为默认 JSON 语法的替代。 We found it pretty useful, eg for configuration files.我们发现它非常有用,例如用于配置文件。

Note that our JSONReformat() function is very fast.请注意,我们的JSONReformat()函数非常快。 It converts the huge 190 MB of unconformatable JSON content from CityLots into 400 MB of beautified JSON (intended and with line fields) in 1.4 seconds.它在 1.4 秒内将来自CityLots 的190 MB 的巨大的不符合格式的JSON 内容转换为 400 MB 的美化 JSON(预期和带有行字段)。 SuperObject is just able to read it in 10 seconds, and uses 1.1 GB just for storing the 190 MB of content. SuperObject只能在 10 秒内读取它,并且仅使用 1.1 GB 来存储 190 MB 的内容。 And DBXJSON is not even able to load the data: it consumes all 32 bit memory - under Win64 (XE6), it takes 50 seconds and uses 3 GB of RAM to read the 190 MB of JSON.而且 DBXJSON 甚至无法加载数据:它消耗了所有 32 位内存 - 在 Win64 (XE6) 下,它需要 50 秒并使用 3 GB 的 RAM 来读取 190 MB 的 JSON。 See this article for some numbers .有关一些数字,请参阅本文

Use the superobject library, make sure that you use the latest version from the repository file, not the 1.2.4 ZIP .使用超级对象库,确保使用存储库文件中的最新版本,而不是 1.2.4 ZIP

Then you can format your TSuperObject object with .AsJSON(true) (the 'true' does the trick).然后你可以用.AsJSON(true)格式化你的 TSuperObject 对象('true' 就行了)。

[ Note that you have no control over the order in which the JSON fields are displayed ] [请注意,您无法控制 JSON 字段的显示顺序]

[ And to create your object from the string: var lJSON : ISuperObject; lJSON := SO(string); [ 并从字符串创建您的对象: var lJSON : ISuperObject; lJSON := SO(string); var lJSON : ISuperObject; lJSON := SO(string); ] ]

This is a bit old, but if anyone is interested Delphi's native System.JSON unit can do this too.这有点旧,但如果有人感兴趣,Delphi 的原生 System.JSON 单元也可以做到这一点。 Sample uses a TMemo and a TButton to format the 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;

If you're working with Delphi XE or newer, you can use thedelphi-xe-json library如果您使用的是 Delphi XE 或更新版本,则可以使用delphi-xe-json

function PrettyPrint (aJSON : string) : string;
var
  jo : IJSONObject
begin
  jo := TJSON.NewObject(aJSON);
  result := jo.ToString(true);
end;

Delphi 10.4, no REST.Json required: Delphi 10.4,不需要REST.Json

function Format_JSON(Value: String; Indentation: Integer = 4): String; inline;
var
  JV: TJSONValue; // not TJSONObject
begin
  JV:= nil;

  try
    try
      JV:= TJSONObject.ParseJSONValue(Value); // TJSONObject.ParseJSONValue(Value) as TJSONObject cast fails
      Result := JV.Format(Indentation);
    except
      on E: Exception do Log_Exception(E);
    end;
  finally
    FreeAndNil(JV);
  end;
end;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM