json-c 库中是在嵌入式开发中常用的库。因为很多地方都以json数据数据交互协议, 尤其嵌入式web数据交互时通常会用到json格式, 因此如果需要在产品端进行json数据解析 , json-c 是一个比较不错的选择。
本次我主要是对json数据的解析 , 主要是整型 , 字符串 和数据 , 进行解析。
一.将json格式的数据转化为一个json对象 :jsonobj
那么首先需要的就是有一个可以被解析的json对象。因为从web来的的数据一般是字符串也可以纯文本,而json-c对这两种都支持。先说json格式的字符串转成json对象:
1json_object* json_tokener_parse(const char *str);
或者以具有json格式文本内容的文本文件转化为json对象:
1json_object* json_object_from_file(const char *filename);
这两种方式都可以轻松将json格式的数据转化为json对象。并进一步进行解析。
二.对json对象进行解析
这个解析主要分两步走
第一步:根据键名,从json对象中获取对应数据的json对象
第二步: 根据数据类型,将数据对应的json对象转化为对应类型的数据
主要接口:
1json_bool json_object_object_get_ex(struct json_object* obj, const char *key, struct json_object **value);
这个是一个增强的接口,
参数说明:
obj:源json对象 , 即需要从obj这个json对象取数据
key: 需要取数据的键名
value: 用于存放获取的对应数据的json对象,注意这里一定传入的是二级指针。不用传入实体
将对应的整型数据json数据转成对应的整型数据
1int32_t json_object_get_int(struct json_object *obj);
将对应的json字符串转换为字符串数据
1extern const char* json_object_get_string(struct json_object *obj);
提取json数组中元素,当然这个元素也是一个json对象
1json_object* json_object_array_get_idx(struct json_object *obj , int idx);
参数说明:
obj:json数据对象
idx:数据元素的脚标索引
当然还有其他的接口就不说了, 目前就对数据进行解析, 没有对数据封装成json数据
但是这个json数据解析需要注意释放内存
以上接口产生的json对象 , 都需分别用
1json_object_put(struct json_object *obj);
对内存进行释放
最后贴一个测试代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251#include <stdio.h> #include <Alooper/Errors.h> #include <linux/types.h> #include <jsonc/json.h> typedef long long off64_t; #include <ghttp/ghttp.h> /**是否强制退出http处理**/ static int mCancelHttp = 0; char buffer[4096]; /***专辑列表数据***/ typedef struct speciallist_s{ // int keyId; char id[10]; char name[128]; int type; int count; }speciallist_t; char *jsonstr = "{"data":[{"id":"100101","name":"小学语文一年级上(人教版)","type":0,"count":20},{"id":"100102","name":"小学语文一年级下(人教版)","type":1,"count":37},{"id":"100103","name":"小学语文二年级上(人教版)","type":1,"count":40},{"id":"100104","name":"小学语文二年级下(人教版)","type":1,"count":41},{"id":"100105","name":"小学语文三年级上(人教版)","type":1,"count":35},{"id":"100106","name":"小学语文三年级下(人教版)","type":1,"count":32},{"id":"100107","name":"小学语文四年级上(人教版)","type":1,"count":32},{"id":"100108","name":"小学语文四年级下(人教版)","type":1,"count":32},{"id":"100109","name":"小学语文五年级上(人教版)","type":1,"count":36},{"id":"100110","name":"小学语文五年级下(人教版)","type":1,"count":30},{"id":"100111","name":"小学语文六年级上(人教版)","type":1,"count":33},{"id":"100112","name":"小学语文六年级下(人教版)","type":1,"count":32},{"id":"100201","name":"小学英语一年级上(人教版)","type":1,"count":38},{"id":"100202","name":"小学英语一年级下(人教版)","type":1,"count":38},{"id":"100203","name":"小学英语二年级上(人教版)","type":1,"count":38},{"id":"100204","name":"小学英语二年级下(人教版)","type":1,"count":38},{"id":"100205","name":"小学英语三年级上(人教版)","type":1,"count":60},{"id":"100206","name":"小学英语三年级下(人教版)","type":1,"count":60}],"total":18,"flag":99,"result":0}"; /********* 数据解析 ***********/ int dedata(char *databuf) { int i = 0; int total = 0; int flag = 0; int result = 0; int ret = -1; speciallist_t listdata[20]; if(NULL == databuf) { printf("the databuf is NULL ...n"); } json_object *jsonobj = NULL; json_object *tmpjson = NULL; json_object *datajson = NULL; json_object *listjson = NULL; printf("databuf :[%s], size:[%d]n",databuf , strlen(databuf)); //jsonobj = json_object_new_string_len(databuf , strlen(databuf)); // jsonobj = json_object_new_string(jsonstr); jsonobj = json_tokener_parse(databuf); if(NULL == jsonobj) { printf("the jsonobj is error n"); } // printf("json:%s",json_object_to_json_string(jsonobj)); ret =json_object_object_get_ex(jsonobj , "total" , &tmpjson); if(!ret) { printf("get jsondata error ...n"); } if(NULL == tmpjson) { printf("the tmpjson : [%s]n",json_object_to_json_string(tmpjson)); } /**获取total***/ total = json_object_get_int(tmpjson); json_object_put(tmpjson); // tmpjson = NULL; /***获取flag***/ json_object_object_get_ex(jsonobj , "flag" , &tmpjson); flag = json_object_get_int(tmpjson); json_object_put(tmpjson); /***获取result***/ json_object_object_get_ex(jsonobj , "result" , &tmpjson); result = json_object_get_int(tmpjson); json_object_put(tmpjson); /***获取data***/ json_object_object_get_ex(jsonobj , "data" , &tmpjson); for(i = 0 ; i < total ; i++) { datajson = json_object_array_get_idx(tmpjson , i); json_object_object_get_ex(datajson , "id" , &listjson); strcpy(listdata[i].id , json_object_get_string(listjson)); json_object_object_get_ex(datajson , "name" , &listjson); strcpy(listdata[i].name , json_object_get_string(listjson)); json_object_object_get_ex(datajson , "type" , &listjson); listdata[i].type = json_object_get_int(listjson); json_object_object_get_ex(datajson , "count" , &listjson); listdata[i].count = json_object_get_int(listjson); json_object_put(listjson); } json_object_put(tmpjson); /***释放json对象***/ json_object_put(jsonobj); printf("------------the data -----------------n"); printf("{nt"data":ntt[n"); for(i = 0 ; i < total ; i++) { printf("ttt{"id":"%s","name":"%s","type":%d,"count":%dn",listdata[i].id , listdata[i].name,listdata[i].type,listdata[i].count); } printf("tt],nt"total":%d,nt"flag":%d,nt"result":%dn}",total,flag , result); return 0; } /***从外部线程中断http请求 , 避免网络差时卡在http请求中***/ void http_abort(void) { mCancelHttp = 1; } int http_interrupt(void *arg) { static i = 0; printf("http is been interrupt :%d n",i++); return *(int *)arg; } /******* 获取重定向url *******/ static char *_get_redirect_url(char *url , ghttp_request *req) { const char *newUri = ghttp_get_resp_header(req , http_hdr_Location); if(NULL == newUri) { return NULL; } if(newUri[0] == '/') { char *p1 , *p2; int len; p1 = strstr(url , "://")+3; p2 = strstr(p1 , "/"); if(NULL == p2) { p2 = url + strlen(url); } len = p2 - url; p1 = malloc(len + strlen(newUri)+1); if(NULL == p1) { printf("malloc errorn"); return NULL; } memcpy(p1 , url , len); strcpy(p1+len , newUri); return p1; } else { return strdup(newUri); } } int http_process(char *file_url) { ghttp_request *req = NULL; ghttp_status status; int statusCode; int ret; int filesize; int redirect_cnt = 0; char *url = file_url; char *p; bzero(buffer , sizeof(buffer)); /***初始化a-res库****/ //ares_library_init(ARES_LIB_INIT_ALL); AGAIN: req = ghttp_request_new(http_interrupt , &mCancelHttp); if(NULL == req) { printf("request new err !!n"); goto EXIT; } /***设置请求的url**/ if(ghttp_set_uri(req , url) != 0) { printf("set uri err !!n"); goto EXIT; } /***设置自定义http协议头 ,非必须***/ // ghttp_set_header(req , "User-Agent","VLC/2.2.4LibVLC/2.2.4n"); /**设置get方法下载数据**/ ghttp_set_type(req , ghttp_type_get); ghttp_prepare(req); /***连接服务器***/ status = ghttp_connect(req , 011 , 011); // status = ghttp_connect(req , 0 , 4095); if((status != ghttp_done)&&(status != ghttp_error_no_support_range)) { printf("http fail ...n"); goto EXIT; } /****获取http 服务器的响应码***/ statusCode = ghttp_status_code(req); /***处理重定向****/ if(statusCode == 301 || statusCode == 302 || statusCode == 303 || statusCode == 307) { if(redirect_cnt >= 3) { printf("redirect too much times n"); goto EXIT; } char *p = _get_redirect_url(url , req); if(NULL == p) { goto EXIT; } if(redirect_cnt > 0) { free(url); } url = p; redirect_cnt++; ghttp_request_destroy(req); goto AGAIN; } /***开始获取数据***/ filesize = ghttp_get_size(req); ret = ghttp_read(req , buffer , 4095); if(ret < 0) { printf("http get data fail , ret = %dn",ret); } else if(ret == 0) { printf("http get data success filesize :%dn",filesize); } else { printf("http get data ret : %dn",ret); } /****释放http请求资源****/ ghttp_request_destroy(req); if((redirect_cnt > 0)&& (NULL != url)) { free(url); } printf("the data:[%s]n",buffer); /***json 解析****/ printf("-------------------++++josn++++-------------------n"); dedata(buffer); return 0; EXIT: if(NULL != req) { ghttp_request_destroy(req); } if((redirect_cnt > 0)&& (NULL != url)) { free(url); } return -1; } /****main*****/ int main(int argc , char *argv[]) { int ret = -1; char *url="http://xzxtest.com/test/abc/listSubAlbum?sn=10086&flag=0"; ret = http_process(url); return 0; }
最后
以上就是腼腆人生最近收集整理的关于使用json-c 体会的全部内容,更多相关使用json-c内容请搜索靠谱客的其他文章。
发表评论 取消回复