Delphi用QJSON解析JSON格式的數據

原本用superobject來解析JSON已經夠用了,惋惜這個東東不能在移動端使用,因而找到QJSON來處理。json

這是一個國內高手寫開源免費的東西,贊一個。數組

假入數據以下:編碼

{"message":"ok","status":"1","state":"3","data":
[{"time":"2012-07-07 13:35:14","context":"客戶已簽收"},
 {"time":"2012-07-07 09:10:10","context":"離開 [北京石景山營業廳] 派送中,遞送員
[溫],電話[]"},
 {"time":"2012-07-06 19:46:38","context":"到達 [北京石景山營業廳]"},
 {"time":"2012-07-06 15:22:32","context":"離開 [北京石景山營業廳] 派送中,遞送員
[溫],電話[]"},
 {"time":"2012-07-06 15:05:00","context":"到達 [北京石景山營業廳]"},
 {"time":"2012-07-06 13:37:52","context":"離開 [北京_同城中轉站] 發往 [北京石景山
營業廳]"},
 {"time":"2012-07-06 12:54:41","context":"到達 [北京_同城中轉站]"},
 {"time":"2012-07-06 11:11:03","context":"離開 [北京運轉中心駐站班組] 發往 [北京_
同城中轉站]"},
 {"time":"2012-07-06 10:43:21","context":"到達 [北京運轉中心駐站班組]"},
 {"time":"2012-07-05 21:18:53","context":"離開 [福建_廈門支公司] 發往 [北京運轉中
心_航空]"},
 {"time":"2012-07-05 20:07:27","context":"已取件,到達 [福建_廈門支公司]"}
]} 

用QJSON解析以下:spa

procedure TForm15.Button1Click(Sender: TObject);
var
  aqjson,aqjsonarr : TQJSON;
  i : Integer;
  stime, scontext : string;
begin
  aqjson := TQJSON.Create;
  aqjson.parse(memo1.lines.text);
  if aqjson.ValueByName('message', '') = 'ok' then
  begin
    memo2.Clear;
    aqjsonarr := aqjson.ItemByName('data');
    for i := 0 to aqjsonarr.Count - 1 do
    begin
      stime := aqjsonarr.Items[i].ValueByName('time', '');
      scontext := aqjsonarr.Items[i].ValueByName('context', '');

      Memo2.Lines.Add(stime+'----'+scontext);
    end;
  end;
end;

能夠看到QJSON的解析仍是很方便的。code

不過這種格式存在大量冗餘數據——每一個數據項都攜帶了字段信息,其實能夠只返回一次字段信息便可。orm

數據精簡以下:blog

{"message":"ok","status":"1","state":"3","data":
["2012-07-07 13:35:14","客戶已簽收",
 "2012-07-07 09:10:10","離開 [北京石景山營業廳] 派送中,遞送員[溫],電話[]",
]} 

能夠看到數組裏面的串再也不是JSON格式(Key:Value)的了,這時不能再使用ValueByName,而直接使用Value。圖片

procedure TForm15.Button2Click(Sender: TObject);
var
  aqjson,aqjsonarr : TQJSON;
  i : Integer;
  stime, scontext : string;
begin
  aqjson := TQJSON.Create;
  aqjson.parse(memo3.lines.text);
  if aqjson.ValueByName('message', '') = 'ok' then
  begin
    memo2.Clear;
    aqjsonarr := aqjson.ItemByName('data');
    for i := 0 to aqjsonarr.Count - 1 do
    begin
      stime := aqjsonarr.Items[i].ValueByName('time', '');
      scontext := aqjsonarr.Items[i].ToString;

      Memo2.Lines.Add(stime+'----'+scontext);
    end;
  end;
end;

實際編碼中,會存在返回圖片到客戶端的狀況,若是也採用JSON格式傳輸的話,須要把圖片轉成Base64格式的傳包裝,而後再傳輸到客戶端解析。內存

這裏是一個演示,首先把圖片轉成流:字符串

Image1.Picture.Graphic.SaveToStream(ss);

而後編碼成base64格式的:

EncodeStream(ss, ss1);

注意ss和ss1的定義:

var
  ss: TMemoryStream;
  ss1,ss2 : TStringStream;
EncodeStream的調用須要引用EncdDecd.pas單元。

而後把流轉成字符串
var
  sdata : string;
begin
...
  sData := ss1.DataString;
...
end;

再把該字符串包裝到JSON串:

var
  aqjson : TQJSON;
begin
  aqjson := TQJSON.Create;
  aqjson.Parse(memo3.Lines.Text);
...
  aqjson.AddArray('pic').Add.AsString :=sdata;
...
end;

這樣圖片就打包到JSON裏面了,傳到客戶端之後,再反過來解析便可:

ss2 := TStringStream.Create(aqjson.ItemByName('pic').Items[0].value);
DecodeStream(ss2,ss);//將base64字符流還原爲內存流
ss.Position := 0; // 必須
Image2.Picture.Graphic.LoadFromStream(ss);
相關文章
相關標籤/搜索