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:[email protected] 修改時間: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.