一、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"}]}}
View Code
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;
View Code
二 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.

 

 

posted on 2016-02-25 17:04  EEEEEEEEEEEEEEEEEEE  阅读(3575)  评论(0编辑  收藏  举报