В Delphi XE2 мне нужно создать функцию, которая получает JSONValue
и возвращает String
с отступом, как JSONLint. Это JSONValue может быть любым типом JSON, может быть массивом, объектом, даже просто строкой, поэтому я должен убедиться, что эта функция охватывает все типы. Я понятия не имею, с чего начать.
JSONValue в строку с отступом
comment
вы хотите красиво печатать строки json?
- person Marc B   schedule 03.08.2012
Ответы (3)
Вам придется делать это рекурсивно. Что-то вроде этого:
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. Но это должно заставить вас начать.
person
Mason Wheeler
schedule
03.08.2012
Я взял код у Мейсона, сделал упражнение для читателей и поместил его в отдельный блок:
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.
person
Jan Doggen
schedule
30.08.2012
В коде отсутствуют запятые между объектами в массиве.
- person rhody; 08.08.2014
Чтобы дополнить ответ Доггена и Уиллера, я заменил подпрограмму 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;
person
rhody
schedule
07.08.2014