Delphi XE6 原生解析json

Delphi XE6 原生解析json

(2014-07-22 23:22:35)
标签:

it

分类: DelphiXE6
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>原生解析json Delphi <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
        :=Format('%s %s',[TJSONPair(LItem).JsonString.Value, TJSONPair(LItem).JsonValue.Value]);
   end;
end;
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值