• Delphi用QJSON解析JSON格式的数据 【转】


    本来用superobject来解析JSON已经够用了,可惜这个东东不能在移动端使用,于是找到QJSON来处理。

    这是一个国内高手写开源免费的东西,赞一个。

    假入数据如下:

    {"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":"已取件,到达 [福建_厦门支公司]"}
    ]}

    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的解析还是很方便的。

    不过这种格式存在大量冗余数据——每个数据项都携带了字段信息,其实可以只返回一次字段信息即可。

    数据精简如下:

    {"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);

    转自:https://www.cnblogs.com/codingnote/p/3821025.html?utm_source=tuicool&utm_medium=referral

  • 相关阅读:
    两分钟看完一道投机取巧的算法题
    浅谈什么是递归算法
    浅谈什么是图拓扑排序
    what ?1 + 2 + 3 + ⋯ + ∞ = 1/12 ?
    浅谈什么是分治算法
    有点难度,几道和「滑动窗口」有关的算法面试题
    LeetCode 第 2 号问题:两数相加
    面试官,我会写二分查找法!对,没有 bug 的那种!
    基础复习——通过SQLite优化记住密码功能
    基础复习——内容共享——通过ContentProvider封装数据——通过ContentResolver访问数据
  • 原文地址:https://www.cnblogs.com/railgunman/p/10805625.html
Copyright © 2020-2023  润新知