lyhoo

导航

Delphi XE10.4 json生成与解析

    与同事合作,动态为Web程序,传递Josn数据,所以学习Josn,做相关代码,心得如下,便于众人借鉴:

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

    二、结构
    1、构成JSON的Pari
    Pari就是一对的意思,它由二部分组成:
   (1)名称,使用“''”首尾使用双绰号包起来;
   (2)数值,使用中括号“[]”括起来;
   (3)二者之间使用“:”分隔。
    例如:{"value": [95]}
   注意:pari的数值可以由Json的{Pari}取代,这样构成上下二层关系JSON。
    例如:{"value": {"cel":[100,101]}}

    2、分隔字符
    JSONr 数据结构,就是通过pari展现。
    (1)Pari的名称,使用使用“''”首尾使用双绰号首尾包起来。
    (2)Pari的数据数据值“[]”括起来它包含的内容。
    (3)Pari的数据数据值内部并列数据,使用“,”分隔。
    (4)Pari单元,由名称和数值之间用“:”分隔。
    (5)Pari如果构成JSon结构必须用“{}”字符包含它的内容。
    (6)Pari中的字符串,由“"”首尾括起来。 

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

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

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

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

    2、TJSONpari
         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('', TEncoding.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('', TEncoding.UTF8);
  StringStream.LoadFromFile(FileName);
  JsonBoot := TJSONObject.ParseJSONValue(StringStream.DataString) as TJSONObject;
  if checkbox1.Checked
  then Memo1.Text := JsonBoot.Format(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;

posted on 2021-10-31 15:45  刘涌  阅读(1793)  评论(0)    收藏  举报