2

在 Delphi XE2 中,我需要创建一个接收 aJSONValue并返回indented 的函数,String就像JSONLint一样。这个 JSONValue 可以是任何类型的 JSON,可以是数组、对象,甚至只是一个字符串,所以我必须确保使用这个函数涵盖所有类型。我不知道从哪里开始。

4

3 回答 3

4

您必须递归地执行此操作。像这样的东西:

const INDENT_SIZE = 2;

procedure PrettyPrintJSON(value: TJSONValue; output: TStrings; indent: integer = 0); forward;

procedure PrettyPrintPair(value: TJSONPair; output: TStrings; last: boolean; indent: integer);
const TEMPLATE = '%s : %s';
var
  line: string;
  newList: TStringList;
begin
  newList := TStringList.Create;
  try
    PrettyPrintJSON(value.JsonValue, newList, indent);
    line := format(TEMPLATE, [value.JsonString.ToString, Trim(newList.Text)]);
  finally
    newList.Free;
  end;

  line := StringOfChar(' ', indent * INDENT_SIZE) + line;
  if not last then
    line := line + ','
  output.add(line);
end;

procedure PrettyPrintJSON(value: TJSONValue; output: TStrings; indent: integer);
var
  i: integer;
begin
  if value is TJSONObject then
  begin
    output.add(StringOfChar(' ', indent * INDENT_SIZE) + '{');
    for i := 0 to TJSONObject(value).size - 1 do
      PrettyPrintPair(TJSONObject(value).Get(i), output, i = TJSONObject(value).size - 1, indent + 1);
    output.add(StringOfChar(' ', indent * INDENT_SIZE) + '}');
  end
  else if value is TJSONArray then
    //left as an exercise to the reader
  else output.add(StringOfChar(' ', indent * INDENT_SIZE) + value.ToString);
end;

这涵盖了基本原理。警告:我把这个写在我的头上。它可能不正确甚至编译,但这是一般的想法。此外,您必须提出自己的打印 JSON 数组的实现。但这应该让你开始。

于 2012-08-03T14:59:35.547 回答
2

我采用了 Mason 的代码,做了读者练习,并将其放在一个单独的单元中:

unit uJSONTools;

interface

Uses
  Classes, SysUtils, DBXJSON;

procedure PrettyPrintJSON(JSONValue: TJSONValue; OutputStrings: TStrings; indent: integer = 0);
// Formats JSONValue to an indented structure and adds it to OutputStrings

implementation

const INDENT_SIZE = 2;

procedure PrettyPrintPair(JSONValue: TJSONPair; OutputStrings: TStrings; last: boolean; indent: integer);
const TEMPLATE = '%s : %s';
var
  line: string;
  newList: TStringList;
begin
  newList := TStringList.Create;
  try
    PrettyPrintJSON(JSONValue.JsonValue, newList, indent);
    line := format(TEMPLATE, [JSONValue.JsonString.ToString, Trim(newList.Text)]);
  finally
    newList.Free;
  end;

  line := StringOfChar(' ', indent * INDENT_SIZE) + line;
  if not last then
    line := line + ',';
  OutputStrings.add(line);
end;

procedure PrettyPrintArray(JSONValue: TJSONArray; OutputStrings: TStrings; last: boolean; indent: integer);
var i: integer;
begin
   OutputStrings.add(StringOfChar(' ', indent * INDENT_SIZE) + '[');
   for i := 0 to JSONValue.size - 1 do
      PrettyPrintJSON(JSONValue.Get(i), OutputStrings, indent + 1);
   OutputStrings.add(StringOfChar(' ', indent * INDENT_SIZE) + ']');
end;

procedure PrettyPrintJSON(JSONValue: TJSONValue; OutputStrings: TStrings; indent: integer = 0);
var
  i: integer;
begin
  if JSONValue is TJSONObject then
  begin
    OutputStrings.add(StringOfChar(' ', indent * INDENT_SIZE) + '{');
    for i := 0 to TJSONObject(JSONValue).size - 1 do
      PrettyPrintPair(TJSONObject(JSONValue).Get(i), OutputStrings, i = TJSONObject(JSONValue).size - 1, indent + 1);
    OutputStrings.add(StringOfChar(' ', indent * INDENT_SIZE) + '}');
  end
  else if JSONValue is TJSONArray then
    PrettyPrintArray(TJSONArray(JSONValue), OutputStrings, i = TJSONObject(JSONValue).size - 1, indent + 1)
  else OutputStrings.add(StringOfChar(' ', indent * INDENT_SIZE) + JSONValue.ToString);
end;

end.
于 2012-08-30T13:37:03.120 回答
1

为了增加 Doggen 和 Wheeler 的答案,我用以下替换替换了 PrettyPrintArray 例程,以确保数组对象用逗号分隔,否则 prettyprint 输出是无效的 json。

procedure PrettyPrintArray(JSONValue: TJSONArray; OutputStrings: TStrings; last:     boolean; indent: integer);
var i: integer;
begin
   OutputStrings.add(StringOfChar(' ', indent * INDENT_SIZE) + '[');
  for i := 0 to JSONValue.size - 1 do
      begin
      PrettyPrintJSON(JSONValue.Get(i), OutputStrings, indent + 1);
      if i < JSONValue.size - 1 then
         OutputStrings[OutputStrings.Count-1] := OutputStrings[OutputStrings.Count-1] + ',';
      end;
   OutputStrings.add(StringOfChar(' ', indent * INDENT_SIZE) + ']');
end;
于 2014-08-07T22:15:03.530 回答