通過 ISuperObject.AsObject 可獲取一個 TSuperTableString 對象.
TSuperTableString 的常用屬性: count、GetNames、GetValues
var
jo: ISuperObject;
jts: TSuperTableString;
begin
jo := SO('{A:1, B:2, C:3, D:{x:4, y:5, z:6}}');
jts := jo.AsObject;
ShowMessage(IntToStr(jts.count)); // 4
ShowMessage(jts.GetNames.AsString); // ["D","C","B","A"]
ShowMessage(jts.GetValues.AsString); // [{"z":6,"y":5,"x":4},3,2,1]
jts := jo['D'].AsObject;
ShowMessage(IntToStr(jts.count)); // 3
ShowMessage(jts.GetNames.AsString); // ["z","y","x"]
ShowMessage(jts.GetValues.AsString); // [6,5,4]
end;
JSON 本質就是一個二叉樹(SuperObject 支持 32 層深度, 足夠了);
二叉樹的每個節點主要表示一個 Name:Value; 其中的 Name 是字符串, Value 可能是個字符串、整數、數組或另一個 ISuperObject, 所以 Value 的類型只能是 ISuperObject.
描述這個節點的類是 TSuperAvlEntry, 我們可以從一個 TSuperTableString 中枚舉出當前層及的每個 TSuperAvlEntry.
var
jo, io: ISuperObject;
item: TSuperAvlEntry;
begin
jo := SO('{A:1, B:2, C:3, D:{x:4, y:5, z:6}}');
{從 TSuperTableString(這裡是用 jo.AsObject 獲取)中枚舉 TSuperAvlEntry}
Memo1.Clear;
for item in jo.AsObject do
Memo1.Lines.Add(Format('Name: %s; Value: %s', [item.Name, item.Value.AsString]));
{直接從 ISuperObject 中枚舉 "子ISuperObject"}
Memo1.Lines.Add(EmptyStr);
for io in jo do
Memo1.Lines.Add(Format('Value: %s', [io.AsString]));
end;
上面的遍歷都沒有深入下去, 要徹底深入地遍歷需要寫回調函數.
下面寫了兩個回調函數, 第一個沒有考慮數組中的對象:
uses SuperObject;
//使用回調的遍歷過程之一: 沒考慮數組中的對象
procedure Proc1(jo: ISuperObject; var List: TStrings);
var
item: TSuperAvlEntry;
begin
if not Assigned(List) then List := TStringList.Create;
for item in jo.AsObject do
if item.Value.DataType = stObject then
Proc1(item.Value, List) {如果是對象就回調}
else {不是對象就添加到列表}
List.Add(Format('%s : %s', [item.Name, item.Value.AsString]));
end;
//使用回調的遍歷過程之二:
procedure Proc2(jo: ISuperObject; var List: TStrings);
var
i: Integer;
item: TSuperAvlEntry;
begin
if not Assigned(List) then List := TStringList.Create;
for item in jo.AsObject do
begin
if item.Value.DataType = stObject then
Proc2(item.Value, List) {如果是對象就回調}
else begin {不是對象就添加到列表}
List.Add(Format('%s : %s', [item.Name, item.Value.AsString]));
if item.Value.DataType = stArray then begin {如果是數組, 看看裡面是不是有對象}
for i := 0 to item.Value.AsArray.Length - 1 do
if item.Value.AsArray[i].DataType = stObject then
Proc2(item.Value.AsArray[i], List); {如果是對象就再回調}
end;
end;
end;
end;
//調用測試
procedure TForm1.Button1Click(Sender: TObject);
var
jo: ISuperObject;
List: TStrings;
begin
jo := SO('{A:1, B:2, C:3, D:[4, 5, {X:6}, {Y:[7,8,{m:9}]}]}');
Proc1(jo, List);
ShowMessage(List.Text);
List.Clear;
Proc2(jo, List);
ShowMessage(List.Text);
List.Free;
end;