Delphi json操作

    与同事合作,需要动态生成Json,并传递json数据,所以被学习Josn,做相关代码,心得如下,便于众人借鉴:

    一、Josn简介
    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于阅读和编写,同时也易于机器解析和生成。它基于ECMA262语言规范(1999-12第三版)中JavaScript编程语言的一个子集。 JSON采用与编程语言无关的文本格式,但是也使用了类C语言(包括C, C++, C#, Java, JavaScript, Perl, Python等)的习惯,这些特性使JSON成为理想的数据交换格式。
    Delphi2009开始支持Json。

    下图是相关网站的Json结构详细说明(截图),读懂有助您 对Json的理解 。

    二、结构

     1、Json基本结构,对应TJsonObject 

     {“Data”,100}

      2、JSON的Pair,对应TJSONpair
    Pari就是一对的意思,它由二部分组成:
   (1)名称,使用“''”首尾使用双绰号包起来;
   (2)数值,使用中括号“[]”括起来;
   (3)Pair名称、值之间使用“:”分隔;

     (4)  数组值之间使用“,”分隔;

   (5)字符使用“”。
    例如:{"value": [95]}
   注意:Pair的数值可以由Json的{Pari}取代,这样构成上下二层关系JSON。
    例如:{"value": {"cel":[100,101]}}

     3、数组

      (1)由Pair为元素的数组,使用{}括号,,对应TJsonObject

      (2)由数值为元素的数组,使用[]括号,对应TJsonArray  

     4、Json语法(分隔字符)
    JSONr 数据结构,就是通过pair展现。
    (1)Pair的名称,使用使用“''”首尾使用双绰号首尾包起来。
    (2)Pair单元,名称和数值之间用“:”分隔。
    (3)Pair单元的数值,可以是数组,用“[]”首尾包起来。
    (4)数组元素之间,使用“,”分隔。
    (5)Pair单元的数值,也可以是Json,使用“{}”字符首尾包起来。

    (6)甚至数组[]中的元素,也可以是Json

    (7)元素是字符的“"首尾括起来,非字符无需用“"。 

    三、JSON的分层
  (1)一层结构
    1、一个Pair的JSON:
{"Name":["lyhoo"]}                               //  一个Pair数据是字符
{"totla":[100]}                                       //  一个Pair数据是整数

    2、一个Pair的JSON:
{"Velue":[1,2,3,4,5]}                  //  一个Pari数据,Pair的值是个数组
    3、多个Pair并列的JSON:
{"Name":["lyhoo"],"Name1":["lyhoo1"]}      // 二个Pair
{"totla":[100],"sun":[200],"first":[300]}      // 三个Pair
    (2)二层结构
    例1:一个Boot,第二层(一个Pair)
{"Name":{"totla":[100]}}                               // Pair的数值是一个Json结构

    例2:一个Boot,第二层(四个Pair)
{"dDataset":{"city":["上海"],"occupy": [58],"total": [61],"value": [95]}}

    例3:一个Boot,第二层(四个Pair,Pair的数值由数组组成)
{"dDataset":{"city":["上海","北京","杭州","南京"],"occupy": [58, 47, 59, 61],"total": [61, 83, 80, 67],"value": [95, 57, 74, 91]}}
    了解JSON的结构非常必要,对于编辑创建和折分JSON,很有帮助。要今后的生成和折分,都是要分层进行的。 

    三、基本的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对象

    具体说明:

    1、TJSONObject
         AddPair       //  加入Pari(名称,数值)
         GetValue     // 获取Pari
         Get[]            // 获取指定位置Pair对象 
         count           // 构成数组时Pari和个数

    2、TJSONpair
         JsonString      // 获取名称 
         JsonValueg    // 获取数据
     3、TJSONArray
         count             // 数组个数
         add                // 加入值
         AddElement   // 加入元素
         Items[]            // 获取指定位置数据
    以上是最基本的对象的方法。 

    四、生成Json
    1、首先做一个结构图:
    2、依据结构,由下向上逐级,创建JSONObject,若有的Josn结构的值是数组,最后由带入Boot,完成Josn生成.

procedure TMainFrm.Button2Click(Sender: TObject);
var SQL,S,S1,S2,FileName:string;
    MyList1, MyList2:TStringList;
    T:boolean;
    i,M1,M2,M3,M4,M5,M6,M7,M8,M9,M10,M12,M13,M14,M15,M16,Top
    :Integer;
    N1:Double;
    A:array[0..30,0..4] of string;
  JsonBoot,
  Json1,
  Json2,
  Json3,
  Json4  :TJSONObject;
  JsonBootArray,
  JsonArray1,
  JsonArray2,
  JsonArray3,
  JsonArray4  :TJSONArray;
  StringStream:TStringStream;
begin
  MyList1:=TStringList.Create;
  MyList2:=TStringList.Create;
  SQL:='select 分支名称,分支简称 From 分支信息 order by 排序';

  DataModule1.UniQuery1.close;
  DataModule1.UniQuery1.SQL.clear;
  DataModule1.UniQuery1.SQL.Add(SQL);
  DataModule1.UniQuery1.open;
  with DataModule1.UniQuery1 do
  begin
    First;
    while not Eof do
    begin
      T:=False;
      S1:=FieldByName('分支名称').AsString;
      S2:=FieldByName('分支简称').AsString;
      for i:=0 to MyList1.Count-1 do
        if S2=MyList2.Strings[i] then T:=True;
      if not T then
      begin
        MyList1.Add(S1);
        MyList2.Add(S2);
      end;
      Next;
    end;
  end;
  Top:=MyList1.Count;
  for i:=0 to Top-1 do
  begin
    sFZID:=MyList2.Strings[i];
 // 读取床位信息
    SQL:='select 选择,老人姓名,性别,护理等级,状态,照护等级 From 老人床位分布 where (分支='+#39+sFZID+#39+')';
    DataModule1.UniQuery1.close;
    DataModule1.UniQuery1.SQL.clear;
    DataModule1.UniQuery1.SQL.Add(SQL);
    DataModule1.UniQuery1.open;
// 读入数据
    With DataModule1.UniQuery1 do
    begin
      M1:=0;   M2:=0;   M3:=0;   M4:=0;   M5:=0;   M6:=0;   M7:=0;   M8:=0;
      M9:=0;  M10:=0;  M12:=0; M13:=0;  M14:=0;  M15:=0;   M16:=0;
      First;
      while Not Eof do
      begin
        if FieldByName('选择').AsBoolean then
        begin
          if Trim(FieldByName('状态').AsString)='包床' then M10:=M10+1;
          S1:=Trim(FieldByName('老人姓名').AsString);
          S2:=FieldByName('性别').AsString;
          S:=FieldByName('护理等级').AsString;
          M1:=M1+1;                                       // 床数
          if S1<>'' then M2:=M2+1;                        // 人数
          if Pos('男',S2)>0 then M3:=M3+1                 // 男
                            else M4:=M4+1;                // 女
          if pos('专',S)>0 then M5:=M5+1                  // 专护
            else begin
              if pos('重',S)>0 then M6:=M6+1              // 重
                else begin
                  if pos('中',S)>0 then M7:=M7+1          // 中
                    else begin
                      if pos('轻',S)>0 then M8:=M8+1      // 轻
                        else if pos('正常',S)>0 then M9:=M9+1; // 正常
                    end;
                end;
            end;
          S:=FieldByName('照护等级').AsString;
          if S='2' then M12:=M12+1 ;                     // 2级
          if S='3' then M13:=M13+1 ;                     // 2级
          if S='4' then M14:=M14+1 ;                     // 2级
          if S='5' then M15:=M15+1 ;                     // 2级
          if S='6' then M16:=M16+1 ;                     // 2级
        end;
        Next;
      end;
    end;
// 其它数据
      if M2<>0 then
      begin
        N1:=Trunc((M2)*10000/M1) / 100;
        FieldByName('实际入住率').AsFloat:=N1;
        if S<>'' then
        begin
          M11:=StrToInt(S);
          FieldByName('核定床位').Asinteger:=M11;
        end;
        if M11>0 then
        begin
          N2:=Trunc((M2)*10000/M11) / 100;
          FieldByName('核定入住率').AsFloat:=N2;
        end;
      end;
      Post;
    end;
if M1>0 then
      N1:=Trunc((M2)*10000/M1) / 100;
    A[i,0]:=MyList1.Strings[i];    // 机构名称
    A[i,1]:=inttostr(M2);          // 入住人数
    A[i,2]:=inttostr(M1);         // 总床数
    A[i,3]:=FloatTostr(N1);        // 入住率
  end;
  JsonBoot:=TJSONObject.Create;
  Json1   :=TJSONObject.Create;
  JsonBootArray:=TJSONArray.Create;
  JsonArray1:=TJSONArray.Create;
  JsonArray2:=TJSONArray.Create;
  JsonArray3:=TJSONArray.Create;
  JsonArray4:=TJSONArray.Create;

  for I := 0 to Top-1 do
  begin
    jsonArray1.Add(A[i,0]);
    jsonArray2.Add(A[i,1]);
    jsonArray3.Add(A[i,2]);
    jsonArray4.Add(A[i,3]);
  end;
  Json1.AddPair('name',jsonArray1);
  Json1.AddPair('occupy',jsonArray2);
  Json1.AddPair('total',jsonArray3);
  Json1.AddPair('value',jsonArray4);
  Jsonboot.AddPair('dDateset',Json1);
  if checkbox2.Checked then
  begin
    Memo1.Clear;
    if checkbox1.Checked
      then Memo1.Text := JsonBoot.Format(4)
      else Memo1.Text := JsonBoot.ToString;   // 格式化文本
  end;
  FileName:=Edit1.Text;
  StringStream := TStringStream.Create();                      // 生成Json纯文本格式
//  StringStream := TStringStream.Create('', TEncoding.UTF8);  // 生成Json Utf8格式
  StringStream.WriteString(Jsonboot.ToString);
  StringStream.SaveToFile(FileName);
  MyList1.Free;
  MyList2.Free;
end;

    以上生成例3的JSON代码。

    五、遍历Json

var StringStream:TStringStream;
    JsonBoot,Json1,Json2      :TJSONObject;
    JsonPair,JsonPair1,JsonPair2:TJsonPair;
    jsonArray3,jsonArray1,jsonArray2    :TJSONArray;      // JSON数组变量
    FileName:string;
    i,i1,j,j1,k,k1:integer;
    temp: string;                                         // 临时使用变量
    N:Double;
    S,S1,S2,sValue:string;
begin
  FileName:=Edit1.Text;
  JsonBoot:=TJSONObject.Create;
  Json1:=TJSONObject.Create;
  Json2:=TJSONObject.Create;
  JsonPair:=TJsonPair.Create;
  JsonPair1:=TJsonPair.Create;
  JsonPair2:=TJsonPair.Create;
  jsonArray3:=TJSONArray.Create;
  jsonArray1:=TJSONArray.Create;
  jsonArray2:=TJSONArray.Create;

  StringStream := TStringStream.Create('', TEncoding.UTF8);
  StringStream.LoadFromFile(FileName);
  JsonBoot:=TJSONObject.ParseJSONValue(StringStream.DataString) as TJSONObject;
//  memo1.lines.add(Root.Get(i).JsonString.toString + ' = ' + Root.Get(i).JsonValue.ToString);
  for i:=0 to JsonBoot.Count-1 do                       // Boot级
  begin
    S:=JsonBoot.Get(i).JsonString.ToString;             // Key
    S1:=S1+S+#13#10;
    JsonPair:=JsonBoot.Get(i) as TJsonPair;             // Paris
    sValue:=JsonPair.JsonValue.ToString;                // JsonValue
    if POS('{',sValue)>0 then                           // 包含{ 子节点
    begin
      Json1:=JsonPair.JsonValue As TJSONObject;         // 1级
      for j:=0 to Json1.Count-1 do
      begin
        S:=Json1.Get(j).JsonString.ToString;            // Key
        S1:=S1+'    '+S+#13#10;
        JsonPair1:=Json1.Get(j) as TJsonPair;           // Paris
        sValue:=JsonPair1.JsonValue.ToString;
        if POS('{',sValue)>0 then
        begin
          Json2:=JsonPair1.JsonValue As TJSONObject;    // 2级
          for k:=0 to Json2.Count-1 do
          begin
            S:=Json2.Get(k).JsonString.ToString;        // Key
            S1:=S1+'       '+S+#13#10;
            JsonPair2:=Json2.Get(j) as TJsonPair;       // Paris
            sValue:=JsonPair2.JsonValue.ToString;
            if POS('{',sValue)>0 then
            begin
              jsonArray2:=Json2.Get(k).JsonValue as TjsonArray;
              for k1:=0 to jsonArray2.Count-1 do
              S1:=S1+'      '+jsonArray2.Items[k1].Value+#13#10;
            end;
          end;
        end
        else begin
          jsonArray1:=Json1.Get(j).JsonValue as TjsonArray;
          for j1:=0 to jsonArray1.Count-1 do
            S1:=S1+'    '+jsonArray1.Items[j1].Value+#13#10;
        end;
      end;
    end
    else begin
      jsonArray3:=JsonBoot.Get(i).JsonValue as TjsonArray;
      for i1:=0 to jsonArray3.Count-1 do
        S1:=S1+' '+jsonArray3.Items[i1].Value+#13#10;
    end;
  end;
  Memo1.Clear;
  Memo1.Lines.Add(S1);
end;


    建议建立一个递归方法,可以不限层数,遍历各个节点。

    六、其它事项
    1、读入文本文件
   (1)通过TStringStream读取

var StringStream:TStringStream;
    JsonBoot  :TJSONObject;
    FileName:string;
begin
  FileName:=Edit1.Text;
  JsonBoot:=TJSONObject.Create;
  StringStream := TStringStream.Create();                        // 读取纯文本格式Json
//  StringStream := TStringStream.Create('', TEncoding.UTF8);    // 读取Utf8格式Json
  StringStream.LoadFromFile(FileName);
  JsonBoot := TJSONObject.ParseJSONValue(StringStream.DataString) as TJSONObject;
  if checkbox1.Checked
  then Memo1.Text := JsonBoot.Format(4)                          // 格式化文本,行缩进4字符   
  else Memo1.Text := JsonBoot.ToString;                          // 格式化文本
end;


   (2)通过TStringList读取
 

  JSONboot:=TJSONObject.ParseJSONValue(Trim(Memo1.Text)) as TJSONObject; 
  JSONboot:=TJSONObject.ParseJSONValue(Trim(MyList.Text)) as TJSONObject; 


    2、保存json文件

var StringStream:TStringStream;
begin
  FileName:=Edit1.Text;
  StringStream.Create;
  StringStream.WriteString(Jsonboot.ToString);
  StringStream.SaveToFile(FileName);
end;

   3、数组Add指定数据类型

var
  JSONarr: TJSONArray;
  JSONobj: TJSONObject;
begin
  JSONarr := TJSONArray.Create;
  JSONarr.AddElement(TJSONString.Create('abc'));
  JSONarr.AddElement(TJSONNumber.Create(123));
  JSONarr.AddElement(TJSONBool.Create(true));
  JSONobj := TJSONObject.Create;
  JSONobj.AddPair('book', TJSONString.Create('james'));
  JSONobj.AddPair('bank', TJSONNumber.Create(38));
  JSONobj.AddPair('phone', TJSONBool.Create(true));
  JSONobj.AddElement(JSONarr);
end;

GitHub 加速计划 / js / json
17
5
下载
适用于现代 C++ 的 JSON。
最近提交(Master分支:2 个月前 )
960b763e 5 个月前
8c391e04 8 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐