Delphi 解析JSON的方法,就我已知的,有三种:
1. Qjson
2. SuperObject
3. System.JSON (Delphi XE 自带)
为方便看效果, 使用Delphi 2007演示Qjson和SuperObject的使用,使用Delphi XE 10.1Berlin演示System.JSON的使用。
1. Delphi 2007使用Qjson(uses Qjson)和SuperObjec(uses superobject)生成JSON和解析JSON
界面如下:
选择ISuperObject(节点顺序有点无法把控),生成如下JSON:
{"msg":"Success","datas":[{"age":10,"id":1,"name":"测试1"},{"age":10,"id":2,"name":"测试2"},{"age":10,"id":3,"name":"测试3"},{"age":10,"id":4,"name":"测试4"},{"age":10,"id":5,"name":"测试5"}],"time":"2020-12-03 11:18:08","code":0,"check":true}
选择Qjson,生成如下JSON:
{
"code":0,
"msg":"Success",
"check":true,
"datas":[
{
"id":1,
"name":"测试1",
"age":10
},
{
"id":2,
"name":"测试2",
"age":10
},
{
"id":3,
"name":"测试3",
"age":10
},
{
"id":4,
"name":"测试4",
"age":10
},
{
"id":5,
"name":"测试5",
"age":10
}
],
"time":"2020-12-03 11:19:08"
}
可以采用Qjson解析,也可以选择ISuperObject解析:
窗体代码如下:
unit uFrmMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, superobject, qjson;
const
fmt= '{"id": %d, "name": "测试%d", "age": %d}';
icount= 5;
type
TForm1 = class(TForm)
Button1: TButton;
GroupBox1: TGroupBox;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
Button2: TButton;
Memo1: TMemo;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure RadioButton2Click(Sender: TObject);
procedure RadioButton1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
FType: Integer;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
json: ISuperObject;
jsonArr: TSuperArray;
js, jsArr: TQJson;
I: Integer;
begin
Memo1.Lines.Clear;
case FType of
0: begin
json:= SO();
json.S['time']:= FormatDateTime('yyyy-MM-dd hh:mm:ss', Now);
json.B['check']:= True;
json['datas']:= SA([]);
for I := 1 to icount do
json.A['datas'].Add(SO(format(fmt, [I, I, 10])));
json.S['msg']:= 'Success';
json.I['code']:= 0;
Memo1.Lines.Text:= json.AsString;
end;
1: begin
js:= TQJson.Create;
try
js.AddVariant('code', 0); //等价于 js.Add('code').AsInteger:= 0;
js.AddVariant('msg', 'Success'); //等价于 js.Add('msg').AsString:= 'Success';
js.AddVariant('check', True); //等价于 js.Add('check').AsBoolean:= True;
jsArr:= js.AddArray('datas');
for I := 1 to icount do
begin
/// <summary>添加一个数组</summary>
/// <param name="AName">要添加的对象的结点名称</param>
/// <param name="AItems">要添加的数组内容</param>
/// <returns>返回创建的结点实例</returns>
jsArr.Add('', format(fmt, [I, I, 10]));
end;
js.AddVariant('time', FormatDateTime('yyyy-MM-dd hh:mm:ss', Now));
Memo1.Lines.Text:= js.AsString;
finally
FreeAndNil(js);
end;
end;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
json: ISuperObject;
jsonArr: TSuperArray;
js, jsArr: TQjson;
I: Integer;
sJson: string;
lst: TStringList;
begin
sJson:= Memo1.Lines.Text;
case FType of
0: begin
json:= SO(sJson);
if json= nil then
Exit;
lst:= TStringList.Create;
try
lst.Add(Format('%u', [json.I['code']]));
if json.B['check'] then
lst.Add('True')
else
lst.Add('False');
lst.Add(json.S['msg']);
jsonArr:= json.O['datas'].AsArray;
for I := 0 to jsonArr.Length - 1 do
lst.Add(Format('%u %s %u', [jsonArr.O[I].I['id'], jsonArr.O[I].S['name'], jsonArr.O[I].I['age']]));
lst.Add(json.S['time']);
showmessage(lst.text);
finally
FreeAndNil(lst);
end;
end;
1: begin
js:= TQJson.Create;
lst:= TStringList.Create;
try
js.Parse(sJson);
lst.Add(Format('%d', [js.IntByName('code', -1)]));
if js.BoolByName('check', false) then
lst.Add('True')
else
lst.Add('False');
lst.Add(js.ValueByName('msg', ''));
jsArr:= js.ItemByName('datas');
for I := 0 to jsArr.Count - 1 do
lst.Add(Format('%u %s %u', [jsArr.Items[I].IntByName('id', 0)
, jsArr.Items[I].ValueByName('name', '')
, jsArr.Items[I].IntByName('age', 0)]));
lst.Add(js.ValueByName('time', ''));
ShowMessage(lst.Text);
finally
FreeAndNil(js);
FreeAndNil(lst);
end;
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FType:= 0;
end;
procedure TForm1.RadioButton1Click(Sender: TObject);
begin
FType:= 1;
end;
procedure TForm1.RadioButton2Click(Sender: TObject);
begin
FType:= 0;
end;
end.
2. Delphi XE 10.1 Berlin 使用TJSONObject(uses System.JSON)生成JSON和解析JSON
界面如下:
生成如下JSON:
{"code":0,"msg":"Success","check":true,"datas":["{\"id\":1,\"name\":\"测试1\",\"age\":10}","{\"id\":2,\"name\":\"测试2\",\"age\":10}","{\"id\":3,\"name\":\"测试3\",\"age\":10}","{\"id\":4,\"name\":\"测试4\",\"age\":10}","{\"id\":5,\"name\":\"测试5\",\"age\":10}"],"time":"2020-12-03 11:26:12"}
解析效果:
窗体代码如下:
unit uFrmMain;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.JSON;
const
fmt= '{"id":%d,"name":"测试%d","age":%d}';
icount= 5;
type
TForm1 = class(TForm)
Button1: TButton;
GroupBox1: TGroupBox;
RadioButton2: TRadioButton;
Button2: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
js: TJSONObject;
jsArr: TJSONArray;
I: Integer;
begin
Memo1.Lines.Clear;
js:= TJSONObject.Create;
jsArr:= TJSONArray.Create;
try
js.AddPair('code', TJSONNumber.Create(0)); //TJSONNumber支持Double、Integer、Int64
js.AddPair('msg', 'Success'); //默认字符
js.AddPair('check', TJSONTrue.Create); //boolean类型 TJSONTrue TJSONFalse
for I := 1 to icount do
jsArr.Add(format(fmt, [I, I, 10]));
js.AddPair('datas', jsArr);
js.AddPair('time', FormatDateTime('yyyy-MM-dd hh:mm:ss', Now));
Memo1.Lines.Add(js.ToString);
finally
js:= nil;
jsArr:= nil;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
js, jsItem: TJSONObject;
jsArr: TJSONArray;
item: TJSONValue;
I: Integer;
sJson: string;
lst: TStringList;
begin
sJson:= Memo1.Lines.Text;
if sJson= '' then
Exit;
lst:= TStringList.Create;
try
js:= (TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(sJson), 0)) as TJSONObject;
lst.Add(js.GetValue('code').Value);
lst.Add(js.GetValue('msg').Value);
if js.GetValue('check') is TJSONTrue then
lst.Add('True')
else
lst.Add('False');
jsArr:= js.GetValue('datas') as TJSONArray;
for I := 0 to jsArr.Size- 1 do
begin
//jsArr.Get(I) as TJSONObject 竟然报错Invalid class typecast 不知道什么原因
jsItem:= (TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(jsArr.Get(I).Value), 0)) as TJSONObject;
lst.Add(Format('%d %s %d', [
(jsItem.GetValue('id') as TJSONNumber).AsInt,
jsItem.GetValue('name').Value,
(jsItem.GetValue('age') as TJSONNumber).AsInt]));
end;
lst.Add(js.GetValue('time').Value);
ShowMessage(lst.Text);
finally
FreeAndNil(lst);
end;
end;
end.
从实际使用效果看,Qjson最好使用,其次是ISuperObject. XE版本自带的TJSONObject有点用不习惯,用熟练了该可以吧。