方提供的对于JSON操作的单元是:system.JSON
Delphi JSON 常用对象
编号 对象 说明
1 TJSONValue 所有JSON类的祖先,包括以下锁有对象
2 TJSONObject 一个JSON对象,对应一段JSON字符串
3 TJSONPair 代表一个Key-Value的JSON对,包括josnString和jsonValue
4 TJSONString 代表一个字符串的JSON节点
5 TJSONNumber 代表一个数值的JSON节点,可以是整形,也可以是浮点型(日期是浮点型)
6 TJSONBool 代表一个布尔型的JSON节点
7 TJSONArray 代表一个数组型的JSON节点
8 TJSONTrue 表示一个TJSONBool型的值为True对象
9 TJSONFalse 表示一个TJSONBool型的值为False对象
本文JSON样例,下面程序使用字符串名称为JSONStr替代下面JSON字符串:
{
"name": "张大顺",
"age": 40,
"married": true,
"books": [
"《Web开发人员参考大全》",
"《delphi深度学习》"
],
"organization": {
"oname": "大中华科技",
"oyear": 20
}
}
1.生成SJON
原生方法:
procedure TForm1.Button4Click(Sender: TObject);
var
jo : TJSONObject;
begin
jo := TJSONObject.Create;
try
jo.AddPair('name','张大顺');
jo.AddPair('age',TJSONNumber.Create(40));
jo.AddPair('married', TJSONBool.Create(True));
jo.AddPair('books',TJSONArray.Create
.Add('《Web开发人员参考大全》')
.Add('《delphi深度学习》'));
jo.AddPair('organization',TJSONObject.Create
.AddPair('oname','大中华科技')
.AddPair('oyear',TJSONNumber.Create(20)));
Memo2.Text := JSON_Format(jo.ToString);
finally
jo.Free; //切记这里需要释放
end;
end;
也可以使用通过Helper实现的类似SuperObject的写法,使用这个方法,需要引入单元uSZHN_JSON.pas
procedure TForm1.Button5Click(Sender: TObject);
var
jo : TJSONObject;
begin
jo := TJSONObject.Create;
try
jo.S['name'] := '张大顺';
jo.I['age'] := 40;
jo.B['married'] := True;
jo.A['books'] := TJSONArray.Create;
jo.A['books'].Add('《Web开发人员参考大全》').Add('《delphi深度学习》');
jo.O['organization'] := TJSONObject.Create;
jo.O['organization'].S['oname'] := '大中华科技';
jo.O['organization'].I['oyear'] := 20;
{
//也可以如下:
jo.O['organization'] := TJSONObject.Create.AddPair('oname','大中华科技');
jo.O['organization'].I['oyear'] := 20;
}
Memo2.Text := JSON_Format(jo.ToString);
finally
jo.Free; //切记这里需要释放
end;
end;
2. 解析JSON
procedure TForm1.Button6Click(Sender: TObject);
var
jo : TJSONObject;
name : string;
age : integer;
married : Boolean;
bookname : string;
oname : string;
begin
jo := TJSONObject.ParseJSONValue(JSONStr) as TJSONObject;
if jo = nil then
begin
//解析失败,不是JSON格式的字符串
Exit;
end;
try
//获取姓名
name := jo.S['name']; //张大顺
//获取年龄
age := jo.I['age']; //40
married := jo.B['married']; //true
bookname := jo.A['books'].Items[0].ToString; // 《Web开发人员参考大全》
oname := jo.O['organization'].S['oname']; // '大中华科技';
age := jo.O['organization'].I['oyear']; // 20;
finally
jo.Free; //切记这里需要释放
end;
end;
3. 删除JSON项
procedure TForm1.Button7Click(Sender: TObject);
var
jo : TJSONObject;
name : string;
age : integer;
married : Boolean;
bookname : string;
oname : string;
begin
jo := TJSONObject.ParseJSONValue(JSONStr) as TJSONObject;
if jo = nil then
begin
//解析失败,不是JSON格式的字符串
Exit;
end;
try
//删除name
jo.Remove('name'); //直接输入需要删除的项目名,这句没有加free是因为helper里边已经加了
//也可以使用下面语句,注意一定要加上free,否则会产生内存泄露
//jo.RemovePair('name').Free; //这是原生的用法
//删除数组中项目
jo.A['books'].Remove(0).free; //删除数组中的第一项:《Web开发人员参考大全》
Memo2.Text := JSON_Format( jo.ToString);
finally
jo.Free; //切记这里需要释放
end;
end;
删除后的结果:
{
"age": 40,
"married": true,
"books":
[
"《delphi深度学习》"
],
"organization":
{
"oname": "大中华科技",
"oyear": 20
}
}
4. JSON数组操作
样例代码一、
procedure TForm1.Button8Click(Sender: TObject);
var
jo : TJSONObject;
ja : TJSONArray;
begin
jo := TJSONObject.ParseJSONValue(JSONStr) as TJSONObject;
if jo = nil then //如果jo不是JSON对象,直接退出
exit;
ja := TJSONArray.Create;
try
ja.Add('增加一个字符串');
ja.Add(1024); //增加数字1024
ja.Add(False); //增加布尔值 False
ja.Add(TJSONObject.Create.AddPair('street','st 208')); //直接增加一个对象
jo.AddPair('数组',ja);
Memo2.Text := JSON_Format(jo.ToString);
finally
jo.Free;
//注意 ja 不需要释放,因为在释放 jo的时候系统会自动释放
end;
end;
执行后结果:
{
"name": "张大顺",
"age": 40,
"married": true,
"books":
[
"《Web开发人员参考大全》",
"《delphi深度学习》"
],
"organization":
{
"oname": "大中华科技",
"oyear": 20
},
"数组":
[
"增加一个字符串",
1024,
false,
{
"street": "st 208"
}
]
}
样例代码二、
procedure TForm1.Button9Click(Sender: TObject);
var
jo : TJSONObject;
ja : TJSONArray;
i : Byte;
begin
ja := TJSONArray.Create; //创建数组对象
try
for i := 1 to 3 do
begin
jo := TJSONObject.Create; //创建数组元素,是JSON对象
jo.S['name'] := 'sensor' + i.ToString;
jo.I['index']:= i;
ja.Add(jo); //将数组元素增加到数组中
end;
Memo2.Text := JSON_Fromat_Array(ja);
finally
ja.Free; //注意 jo 不需要释放,因为在释放 ja的时候系统会自动释放
end;
end;
执行结果:
[
{
"name": "sensor1",
"index": 1
},
{
"name": "sensor2",
"index": 2
},
{
"name": "sensor3",
"index": 3
}
],
总结:
作为对象内嵌元素的对象是不需要释放的,只需要释放最外对象即可;
如果删除元素,不管是删除数组中的元素还是删除JSON对象,都需要Free,否则会产生内存泄漏(测试5万次就会有明显累积);
使用TJSONObject的助手单元uSZHN_JSON.pas,操作JSON会书写更加简便;
{
if Trim(Memo1.Text) = '' then
begin
ShowMessage('要解析数据不能为空!');
end
else
begin
JSONObject := nil;
try
{ 从字符串生成JSON }
JSONObject := TJSONObject.ParseJSONValue(Trim(Memo1.Text)) as TJSONObject;
if JSONObject.Count > 0 then
begin
{ 1,遍历JSON数据 }
Memo2.Lines.Add('遍历JSON数据:' + #13#10);
Memo2.Lines.Add('JSON数据数量:' + IntToStr(JSONObject.Count));
for i := 0 to JSONObject.Count - 1 do
begin
if i = 0 then
begin
temp := JSONObject.Get(i).ToString + #13#10;;
end
else
begin
temp := temp + JSONObject.Get(i).ToString + #13#10;
end;
end;
{ output the JSON to console as String }
Memo2.Lines.Add(temp);
Memo2.Lines.Add('------------------------------');
{ 2,按元素解析JSON数据 }
Memo2.Lines.Add('按元素解析JSON数据:' + #13#10);
temp := 'name = ' + JSONObject.Values['name'].ToString + #13#10;
Memo2.Lines.Add(temp);
// json数组
jsonArray := TJSONArray(JSONObject.GetValue('other'));;
if jsonArray.Count > 0 then
begin
// 得到JSON数组字符串
temp := 'other = ' + JSONObject.GetValue('other').ToString + #13#10;
// 循环取得JSON数组中每个元素
for i := 0 to jsonArray.Size - 1 do
begin
temp := temp + IntToStr(i + 1) + ' : ' + jsonArray.Items[i]
.Value + #13#10;
end;
end;
Memo2.Lines.Add(temp);
end
else
begin
temp := '没有数据!';
Memo2.Lines.Add(temp);
end;
finally
JSONObject.Free;
end;
end;
{**************************************
时间:2021-06-18
2023-07-15 增加了删除函数
功能:1 实现delphi原生的JSON操作为 S[] 操作方式
作者:sensor QQ:910731685
}
unit uJSON_Helper;
interface
uses
//System.Classes,
//System.Types,
//System.DateUtil,
//System.Generics.Collections,
//System.SysUtils,
System.JSON;
type
TJSONObjectHelper = class helper for TJSONObject
private
function Get_ValueS(PairName : string) : string;
procedure Set_ValueS(PairName,PairValue : string);
function Get_ValueI(PairName : string) : Integer;
procedure Set_ValueI(PairName : string; PairValue : Integer);
function Get_ValueI64(PairName : string) : Int64;
procedure Set_ValueI64(PairName : string; PairValue : Int64);
function Get_ValueD(PairName : string) : TDateTime;
procedure Set_ValueD(PairName : string; PairValue : TDateTime);
function Get_ValueB(PairName : string) : Boolean;
procedure Set_ValueB(PairName : string; PairValue : Boolean);
function Get_ValueA(PairName : string) : TJSONArray;
procedure Set_ValueA(PairName : string; PairValue : TJSONArray);
function Get_ValueO(PairName : string) : TJSONObject;
procedure Set_ValueO(PairName : string; PairValue : TJSONObject);
//2023-07-15
function Get_ValueExists(PairName : string) : Boolean;
function Get_ValueDelete(PairName : string) : Boolean;
public
//判断某个字段是否存在
function PairExists(PairName : string) : Boolean;
function DeletePair(PairName : string) : Boolean; //删除某个节点,如果节点存在则返回True,否则返回False,但执行命令后,肯定节点不存在了。
//定义字段读取函数
property S[PairName : string] : string read Get_ValueS write Set_ValueS;
property I[PairName : string] : integer read Get_ValueI write Set_ValueI;
property I64[PairName : string] : Int64 read Get_ValueI64 write Set_ValueI64;
property D[PairName : string] : TDateTime read Get_ValueD write Set_ValueD;
property B[PairName : string] : Boolean read Get_ValueB write Set_ValueB;
property A[PairName : string] : TJSONArray read Get_ValueA write Set_ValueA;
property O[PairName : string] : TJSONObject read Get_ValueO write Set_ValueO;
//2023-07-15 增加
property Exists[PairName : string] : Boolean read Get_ValueExists; //只读属性
property Delete[PairName : string] : Boolean read Get_ValueDelete; //删除某个节点,如果节点存在则返回True,否则返回False,但执行命令后,肯定节点不存在了。
end;
implementation
{ TJSONObjectHelper }
function TJSONObjectHelper.Get_ValueS(PairName: string): string;
var
js : TJSONString;
begin
if PairName = '' then Exit;
if Self.TryGetValue(PairName,js) then
Result := js.Value
else
Result := '';
end;
function TJSONObjectHelper.PairExists(PairName: string): Boolean;
begin
Result := Self.Values[PairName] <> nil;
end;
procedure TJSONObjectHelper.Set_ValueS(PairName, PairValue: string);
var
js : TJSONString;
begin
//1. 首先查找有没有该字段, 如果有,则直接删除
if Self.TryGetValue(PairName,js) then
begin
Self.RemovePair(PairName).Free; //如果没有free,就会产生内存泄露
end;
//2. 然后在增加
Self.AddPair(PairName, PairValue);
end;
function TJSONObjectHelper.Get_ValueI(PairName: string): Integer;
var
ji : TJSONNumber;
begin
if PairName = '' then Exit(0);
if Self.TryGetValue(PairName,ji) then
Result := ji.AsInt
else
Result := 0;
end;
procedure TJSONObjectHelper.Set_ValueI(PairName: string; PairValue: Integer);
var
jn : TJSONNumber;
begin
//1. 首先查找有没有该字段, 如果有,则直接删除
if Self.TryGetValue(PairName,jn) then
Self.RemovePair(PairName).Free;
//2. 然后在增加
Self.AddPair(PairName, TJSONNumber.Create(PairValue));
end;
function TJSONObjectHelper.Get_ValueD(PairName: string): TDateTime;
var
ji : TJSONNumber;
begin
if PairName = '' then Exit(0);
if Self.TryGetValue(PairName,ji) then
Result := ji.AsDouble
else
Result := 0;
end;
function TJSONObjectHelper.Get_ValueDelete(PairName: string): Boolean;
begin
if not Self.PairExists(PairName) then Exit(False);
Self.RemovePair(PairName).Free;
Result := True;
end;
function TJSONObjectHelper.Get_ValueExists(PairName: string): Boolean;
begin
Result := Self.Values[PairName] <> nil;
end;
procedure TJSONObjectHelper.Set_ValueD(PairName: string; PairValue: TDateTime);
var
jn : TJSONNumber;
begin
//1. 首先查找有没有该字段, 如果有,则直接删除
if Self.TryGetValue(PairName,jn) then
Self.RemovePair(PairName).Free;
Self.AddPair(PairName, TJSONNumber.Create(PairValue));
end;
function TJSONObjectHelper.Get_ValueB(PairName: string): Boolean;
var
jb : TJSONBool;
begin
if PairName = '' then Exit(False);
if Self.TryGetValue(PairName,jb) then
Result := jb.AsBoolean
else
Result := False;
end;
procedure TJSONObjectHelper.Set_ValueB(PairName: string; PairValue: Boolean);
var
jb : TJSONBool;
begin
//1. 首先查找有没有该字段, 如果有,则直接删除
if Self.TryGetValue(PairName,jb) then
Self.RemovePair(PairName).Free;
Self.AddPair(PairName, TJSONBool.Create(PairValue));
end;
function TJSONObjectHelper.Get_ValueI64(PairName: string): Int64;
var
ji : TJSONNumber;
begin
if PairName = '' then Exit(0);
if Self.TryGetValue(PairName,ji) then
Result := ji.AsInt64
else
Result := 0;
end;
procedure TJSONObjectHelper.Set_ValueI64(PairName: string; PairValue: Int64);
var
jn : TJSONNumber;
begin
//1. 首先查找有没有该字段, 如果有,则直接删除
if Self.TryGetValue(PairName,jn) then
Self.RemovePair(PairName).Free;
Self.AddPair(PairName, TJSONNumber.Create(PairValue));
end;
function TJSONObjectHelper.DeletePair(PairName: string): Boolean;
begin
if not Self.PairExists(PairName) then Exit(False);
Self.RemovePair(PairName).Free;
Result := True;
end;
function TJSONObjectHelper.Get_ValueA(PairName: string): TJSONArray;
begin
if PairName = '' then Exit(nil);
Self.TryGetValue(PairName,Result);
end;
procedure TJSONObjectHelper.Set_ValueA(PairName: string; PairValue: TJSONArray);
var
ja : TJSONArray;
begin
//1. 首先查找有没有该字段, 如果有,则直接删除
if Self.TryGetValue(PairName,ja) then
Self.RemovePair(PairName).Free;
Self.AddPair(PairName, PairValue);
end;
function TJSONObjectHelper.Get_ValueO(PairName: string): TJSONObject;
var
jo : TJSONObject;
begin
if PairName = '' then Exit(nil);
if Self.TryGetValue(PairName,jo) then
Result := jo
else
Result := nil;
end;
procedure TJSONObjectHelper.Set_ValueO(PairName: string; PairValue: TJSONObject);
var
jo : TJSONObject;
begin
//1. 首先查找有没有该字段, 如果有,则直接删除
if Self.TryGetValue(PairName,jo) then
Self.RemovePair(PairName).Free;
Self.AddPair(PairName, PairValue as TJSONObject);
end;
end.