Delphi JSON


方提供的对于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.
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值