Json结构、创建与解析
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;
更多推荐
所有评论(0)