使用SuperObject
库时,单个JSON对象当前会缩进:
{
"name": "value",
"int_arr": [
1,2,3],
"obj_arr": [
{
"this": "that"
},{
"some": "thing"
}],
"another": 123
}
然而,这种缩进/格式不一样"用户友好"或者"人类可读"因为JSON被大肆宣传。我理解用计算机语言,这并不一定重要,但我想将其格式化为:
{
"name": "value",
"int_arr": [1,2,3],
"obj_arr": [
{
"this": "that"
},
{
"some": "thing"
}
],
"another": 123
}
例如,当使用JSONLint验证/格式化JSON代码时,它会以更清晰的方式执行此操作。
如何修改SuperObject
库以使其格式化不同?库中是否有特定的位置来定义这些格式规则?或者我是否需要深入研究许多不同地方的代码来改变它?
答案 0 :(得分:3)
感谢David A
的评论,实现这些更改相当简单(格式化源代码并了解库代码的工作方式)。所有格式都在TSuperObject.Write
中实现,所有这些更改都可以在此处进行。
只有一个我无法弄清楚的问题,即除了对象之外的类型数组 - 值将转到下一行。但至少数组结尾和对象数组都有所需的换行符和缩进。
以下是TSuperObject.Write
的修改版本(大多数子程序未包含以节省空间)。更改评论:
常数:
const
TOK_SP: PSOChar = #32#32; //<-- added another #32
子程序:
procedure _indent(I: shortint; r: boolean);
begin
Inc(level, I);
if r then
with writer do
begin
{$IFDEF MSWINDOWS}
Append(TOK_CRLF, 2);
{$ELSE}
Append(TOK_LF, 1);
{$ENDIF}
for I := 0 to level - 1 do
Append(TOK_SP, 2); //<-- changed 1 to 2
end;
end;
程序正文:
begin
if FProcessing then
begin
Result := writer.Append(TOK_NULL, 4);
Exit;
end;
FProcessing := true;
with writer do
try
case FDataType of
stObject:
if FO.c_object.FCount > 0 then
begin
k := 0;
Append(TOK_CBL, 1);
if indent then
_indent(1, false);
if ObjectFindFirst(Self, iter) then
repeat
{$IFDEF SUPER_METHOD}
if (iter.val = nil) or not ObjectIsType(iter.val, stMethod) then
begin
{$ENDIF}
if (iter.val = nil) or (not iter.val.Processing) then
begin
if (k <> 0) then
Append(TOK_COM, 1);
if indent then
_indent(0, true);
Append(TOK_DQT, 1);
if escape then
DoEscape(PSOChar(iter.key), Length(iter.key))
else
DoMinimalEscape(PSOChar(iter.key), Length(iter.key));
if indent then
Append(ENDSTR_A, 3)
else
Append(ENDSTR_B, 2);
if (iter.val = nil) then
Append(TOK_NULL, 4)
else
iter.val.Write(writer, indent, escape, level);
Inc(k);
end;
{$IFDEF SUPER_METHOD}
end;
{$ENDIF}
until not ObjectFindNext(iter);
ObjectFindClose(iter);
if indent then
_indent(-1, true);
Result := Append(TOK_CBR, 1);
end
else
Result := Append(TOK_OBJ, 2);
stBoolean:
begin
if (FO.c_boolean) then
Result := Append(TOK_TRUE, 4)
else
Result := Append(TOK_FALSE, 5);
end;
stInt:
begin
str(FO.c_int, st);
Result := Append(PSOChar(SOString(st)));
end;
stDouble:
Result := Append(PSOChar(SOString(gcvt(FO.c_double, 15, fbuffer))));
stCurrency:
begin
Result := Append(PSOChar(CurrToStr(FO.c_currency)));
end;
stString:
begin
Append(TOK_DQT, 1);
if escape then
DoEscape(PSOChar(FOString), Length(FOString))
else
DoMinimalEscape(PSOChar(FOString), Length(FOString));
Append(TOK_DQT, 1);
Result := 0;
end;
stArray:
if FO.c_array.FLength > 0 then
begin
Append(TOK_ARL, 1);
if indent then
_indent(1, true);
k := 0;
j := 0;
while k < FO.c_array.FLength do
begin
val := FO.c_array.GetO(k);
{$IFDEF SUPER_METHOD}
if not ObjectIsType(val, stMethod) then
begin
{$ENDIF}
if (val = nil) or (not val.Processing) then
begin
if (j <> 0) then begin
Append(TOK_COM, 1);
if ObjectIsType(val, stObject) then begin //
if indent then //<-- create line break after object array items
_indent(0, true); //
end; //
end;
if (val = nil) then
Append(TOK_NULL, 4)
else
val.Write(writer, indent, escape, level);
Inc(j);
end;
{$IFDEF SUPER_METHOD}
end;
{$ENDIF}
Inc(k);
end;
if indent then
_indent(-1, true); //<-- changed "false" to "true" to create line break at end of array
Result := Append(TOK_ARR, 1);
end
else
Result := Append(TOK_ARRAY, 2);
stNull:
Result := Append(TOK_NULL, 4);
else
Result := 0;
end;
finally
FProcessing := false;
end;
end;
该代码将产生如下的JSON数据:
{
"name": "value",
"int_arr": [
1,2,3
],
"obj_arr": [
{
"this": "that"
},
{
"some": "thing"
}
],
"another": 123
}