一、Demo一 解析嵌套数组
Json数据
{"code":1,"msg":"","data":{"GradeInfo":[{"gradeid":1,"gradename":"普通介绍人","graderate":0.02}],"UserList":[{"stype":"User","userid":"119110"},{"stype":"User","userid":"11911044"},{"stype":"User","userid":"119110444"},{"stype":"User","userid":"121121"},
{"stype":"User","userid":"13211111113"},{"stype":"User","userid":"abcadsfa"},{"stype":"Customer","userid":"admin"},{"stype":"Shoper","userid":"Shop2222"}]}}
var Jsobj:TJSONObject; i,j:Integer; Jarr:TJSONArray; temp:string; v:string; Jsvalue:Tjsonvalue ; begin Jsobj:=TJSONObject.ParseJSONValue(Memo1.Text) as TJSONObject; temp:=Jsobj.GetValue('data').ToString; Jsobj:=TJSONObject.ParseJSONValue(temp) as TJSONObject; jarr := TJSONArray(Jsobj.GetValue('UserList')); for i := 0 to Jarr.Size-1 do begin v:=(Jarr.Items[i].ToString); Jsobj:=TJSONObject.ParseJSONValue(v) as TJSONObject; // for j := 0 to Jsobj.Count do // begin ShowMessage(Jsobj.GetValue('userid').ToString); //end; end; end;
二 Demo二
Delphi XE5带了system.json单元,原生提供了json支持类。下面是解析json用法说明: 最简单的JSON大致像这样 { "date":"周二(今天, 实时:12℃)", "dayPictureUrl":"http://api.map.baidu.com/images/weather/day/duoyun.png", "nightPictureUrl":"http://api.map.baidu.com/images/weather/night/duoyun.png", "weather":"多云", "wind":"北风微风", "temperature":"15 ~ 6℃" } 对于这种格式比较简单的json,解析是非常容易的 StrJson := RESTResponse1.Content; JSONObject := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(StrJson), 0) as TJSONObject; JSONObject.getValue('date'); 就可以得到date的值。如果像下面的这样结构比较复杂的json,就需要首先分析清楚这个json的格式才能获取成功。 { "error":0, "status":"success", "date":"2014-03-04", "results": [{"currentCity":"成都", "weather_data":[ { "date":"周二(今天, 实时:12℃)", "dayPictureUrl":"http://api.map.baidu.com/images/weather/day/duoyun.png", "nightPictureUrl":"http://api.map.baidu.com/images/weather/night/duoyun.png", "weather":"多云", "wind":"北风微风", "temperature":"15 ~ 6℃" }, { "date":"周三", "dayPictureUrl":"http://api.map.baidu.com/images/weather/day/yin.png", "nightPictureUrl":"http://api.map.baidu.com/images/weather/night/xiaoyu.png", "weather":"阴转小雨", "wind":"北风微风", "temperature":"14 ~ 7℃" }, { "date":"周四", "dayPictureUrl":"http://api.map.baidu.com/images/weather/day/xiaoyu.png", "nightPictureUrl":"http://api.map.baidu.com/images/weather/night/xiaoyu.png", "weather":"小雨", "wind":"北风微风", "temperature":"12 ~ 7℃" }, { "date":"周五", "dayPictureUrl":"http://api.map.baidu.com/images/weather/day/xiaoyu.png", "nightPictureUrl":"http://api.map.baidu.com/images/weather/night/xiaoyu.png", "weather":"小雨", "wind":"南风微风", "temperature":"9 ~ 6℃" } ] } ]} 这是一个嵌套结构,最外层是一个记录,包含"error", "status", "date", "results"四个字段,前三个都是简单的键值对,而“results”是一个数组,目前只有一个元素,即一条记录,这条记录的字段是"currentCity"和"weather_data",再进一步"weather_data"又是一个组数,它有4个元素或者记录,每条记录里包含 "date", "dayPictureUrl","nightPictureUrl", "weather","wind", "temperature"字段。 要想取出里面的"weather_data",利用目前的DBXJSON里的TJSONObject是不能直接取出来的,例如这样 StrJson := RESTResponse1.Content; JSONObject := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(StrJson), 0) as TJSONObject; weather := JSONObject.GetValue('weather_data'); 需要一步一步的走,由于最外面是一个简单的json,可以先取出results,然后再取weather_data。 var JSONObject: TJSONObject; LItem: TJSONValue; LJPair: TJSONPair; weather: TJSONArray; StrJson: String; result: String; i: Integer; begin StrJson := 'xxxxxxx';//假定是上面那个json JSONObject := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(StrJson), 0) as TJSONObject; JSONObject := (JSONObject.GetValue('results') as TJSONArray).Get(0) as TJSONObject; weather := JSONObject.GetValue('weather_data') as TJSONArray; for i := 0 to weather.size - 1 do //应该是4条记录 begin LItem := (weather.Get(i) as TJSONObject).GetValue('weather'); //得到weather的值 result := result '|' LItem.Value; end; end 这段代码只是为了说明使用方法,没有做类型检查,最好在进行类型转换之前用is TJSONArray先判断是不是数组。 原文地址 补充,在原文中,作者没有提到,如何检查一个指定的串值是否存在,比如下面这行代码: weather := JSONObject.GetValue('weather_data'); 如果'weather_data'不存在,JSONObject.GetValue方法是要产生异常的,那么,该如何检查weath_data是否存在呢? 先声明一个 var jsonvalue: Tjsonvalue; 然后,利用JSONObject.TryGetValue方法来检查。 if jsonObject.TryGetValue('weather_data', jsonvalue) then ... 如果weath_data存在,可以进一步通过jsonvalue.value取出其值。 注意,这个jsonvalue不用建立与释放。 2014-11-19 网友发现上文中可能遇到的json串码问题,并给出了解决代码,Delphi <wbr>XE6 <wbr>原生解析jsonDelphi <wbr>XE6 <wbr>原生解析json! procedure TForm1.Button2Click(Sender: TObject); var LJsonArr : TJSONArray; LJsonValue : TJSONValue; LItem : TJSONValue; StrJson,S :string; begin StrJson := RESTresponse1.Content; LJsonArr := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(StrJson),0) as TJSONArray; for LJsonValue in LJsonArr do begin for LItem in TJSONArray(LJsonValue) do S :=Format('%s : %s',[TJSONPair(LItem).JsonString.Value, TJSONPair(LItem).JsonValue.Value]); end; end;
三、Demo三
{ 功能:DelphiXE7中使用JSON ------------------------------------------------------------------------------ 说明: 1,使用Delphi自己带的JSON(system.json)。 2,这仅仅是一个简单例子,以后还会增加演示功能。 ------------------------------------------------------------------------------ 注意: 1,JSON类创建后,里面所有元素不用管释放,JSON类自己管理,千万不要画蛇添足啊!!!!!! ------------------------------------------------------------------------------ 作者:孙玉良 QQ:14667479 Email:sunylat@163.com 修改时间:2014/11/23 00:13 ------------------------------------------------------------------------------ 开发工具:Delphi XE7 测试手机:华为荣耀X1 } unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls, FMX.Layouts, FMX.Memo; type TForm1 = class(TForm) Panel1: TPanel; Memo1: TMemo; Panel2: TPanel; Button1: TButton; Button2: TButton; Memo2: TMemo; Button3: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Button3Click(Sender: TObject); procedure FormResize(Sender: TObject); private { Private declarations } // 重新设置button按钮 procedure ResetButton; public { Public declarations } end; var Form1: TForm1; const // 演示用的JSON jsonString = '{"name":"张三", "other":["中国","程序员"]}'; implementation {$R *.fmx} uses System.json; // Dephi自带的JSON单元 procedure TForm1.Button1Click(Sender: TObject); var JSONObject: TJSONObject; // JSON类 i: Integer; // 循环变量 temp: string; // 临时使用变量 jsonArray: TJSONArray; // JSON数组变量 begin 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; end; // 清空显示数据 procedure TForm1.Button2Click(Sender: TObject); begin Memo1.Text := ''; Memo2.Text := ''; end; // 设置要解析的JSON数据 procedure TForm1.Button3Click(Sender: TObject); begin Memo1.Text := jsonString; end; // 设置要解析的JSON数据 procedure TForm1.FormCreate(Sender: TObject); begin Memo1.Text := jsonString; end; procedure TForm1.FormResize(Sender: TObject); begin // 重新设置button按钮 self.ResetButton; end; // 重新设置button按钮 procedure TForm1.ResetButton; var buttonWidth: Integer; begin buttonWidth := self.Width div 3; Button1.Width := buttonWidth; Button2.Width := buttonWidth; Button3.Width := buttonWidth; end; end.