在Delphi XE2,我需要做的是接收功能JSONValue
并返回一个缩进String
,就像JSONLint 。 这JSONValue可以是任何类型的JSON,可能是一个数组,对象,甚至只是一个字符串,所以我必须确保覆盖所有类型使用此功能。 我不知道从哪里开始。
Answer 1:
你必须递归地做到这一点。 事情是这样的:
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阵列。 但是,这应该让你开始。
Answer 2:
我采纳了梅森的代码,做读者的运动,并把它放在一个单独的单元:
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.
Answer 3:
为了增加通过Doggen和惠勒答案,我取代了常规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;
文章来源: JSONValue to Indented String