一、什么是JSON
JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)。但它并不是编程语言,而是一种可以在服务器和客户端之间传输的轻量级数据交换格式。
二、JSON语法
2.1、JSON基本单元-键值对(key-value)
- 在JSON中,我们使用“键(key):值(value)”表示一组数据,键(key)使用字符串表示,并且是唯一的。键(key)可以简单理解为门牌号,而值(value)可以理解为房间里的内容。
- 键(key)和值(value)之间可以使用空格使排版更加美观;
- 值(value)的内容可以是字符串、数字、布尔类型等;
举个例子:
{
"name": "张三",
"age" : 18,
"sex" : "男"
}
- 值(value)的内容还可以是数组和对象:
{
"ClassName" : "电科一班",
“StudentsNum” : 12,
"StudentInfo" :
[
{
"name": "张三",
"age" : 18,
"sex" : "男"
},
{
"name": "李四",
"age" : 18,
"sex" : "女"
},
]
}
2.2、JSON对象和数组
- JSON对象使用“{}”表示,“{}”中的内容即为对象;
- JSON数组使用“[]”表示,“[]”中的内容即为数组;
{
"Name" : "张三",
"IDInfo":
[
"Nation": "中国",
"Age" : 18,
"Sex" : "男"
]
}
三、CJSON的使用
3.1、CJSON的结构:
/* The cJSON structure: */
typedef struct cJSON {
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
int type; /* The type of the item, as above. */
char *valuestring; /* The item's string, if type==cJSON_String */
int valueint; /* The item's number, if type==cJSON_Number */
double valuedouble; /* The item's number, if type==cJSON_Number */
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;
结构体中的type表示JSON的类型,主要有6种:
- cJSON_False 0 表示JSON初始化为“flase”或者键(key)对应的值(value)为“false”
- cJSON_True 1 表示JSON初始化为“true”或者键(key)对应的值(value)为“true”
- cJSON_NULL 2 表示JSON初始化为“null”或者键(key)对应的值(value)为“null”
- cJSON_Number 3 数据类型为数字
- cJSON_String 4 数据类型为字符串
- cJSON_Array 5 数据类型为数组
- cJSON_Object 6 数据类型为JSON,表示还可以进一步解析
3.2、解析简单的JSON数据
- CJSON中解析相关的函数主要有两个:cJSON_Parse和cJSON_GetObjectItem,前者用于将JSON格式的数据转换成CJSON格式中对应的结构,后者用于获取JSON的键值对的内容。
- CJSON中,有三个特殊值的数据类型,“true”、“false”和“null”,这三个类型,在作为值(value)时,可以不使用双引号
一个简单的例子:
int MyTest()
{
char *json_str = NULL;
cJSON *cjson_str = NULL;
cJSON *cjson_data = NULL;
json_str = "{\"name\": \"zhangsan\", \"age\":18, \"grade\":98.5}";
cjson_data = cJSON_Parse(json_str);//将json字符串转化成CJSON结构体类型的数据
printf("%d\r\n",cjson_data->type);
if(cjson_data)
{
cjson_str = cJSON_GetObjectItem(cjson_data,"name");//获取名称为name的值
if(cjson_str)printf("%s:%s type=%d\r\n",cjson_str->string,cjson_str->valuestring, cjson_str->type);
cjson_str = cJSON_GetObjectItem(cjson_data,"age");//获取名称为age的值
if(cjson_str)printf("%s:%d type=%d\r\n",cjson_str->string,cjson_str->valueint, cjson_str->type);
cjson_str = cJSON_GetObjectItem(cjson_data,"grade");//获取名称为grade的值
if(cjson_str)printf("%s:%.2f type=%d\r\n",cjson_str->string,cjson_str->valuedouble, cjson_str->type);
cJSON_Delete(cjson_data);
}
}
输出结果:
6
name:zhangsan type=4
age:18 type=3
grade:98.50 type=3
复杂点的例子:
int MyTest2()
{
char *str = NULL;
char *json_str = NULL;
cJSON *cjson_str = NULL;
cJSON *cjson_data = NULL;
json_str = "{ \
\"personA\":{\"name\":\"james\",\"pass\":false,\"age\":20}, \
\"personB\":{\"name\":\"joe\",\"pass\":true,\"age\":18} \
}";
int arr_size;
cjson_data = cJSON_Parse(json_str);//将json字符串转化成CJSON结构体类型的数据
if(!cjson_data)
{
printf("json phase error\r\n");
return -1;
}
printf("%d\r\n",cjson_data->type);
cJSON* personA = cJSON_GetObjectItem(cjson_data,"personA");;
//if(personA)printf("%s:%s\r\n",personA->string,personA->child->valuestring);
if(personA)
{
cjson_str = cJSON_GetObjectItem(personA,"name");//获取名称为name的值
if(cjson_str)printf("%s:%s type=%d\r\n",cjson_str->string,cjson_str->valuestring, cjson_str->type);
cjson_str = cJSON_GetObjectItem(personA,"age");//获取名称为age的值
if(cjson_str)printf("%s:%d type=%d\r\n",cjson_str->string,cjson_str->valueint, cjson_str->type);
cjson_str = cJSON_GetObjectItem(personA,"pass");//获取名称为age的值
if(cjson_str)printf("%s:%.2f type=%d\r\n",cjson_str->string,cjson_str->valuedouble, cjson_str->type);
cJSON_Delete(cjson_data);
}
else
{
printf("personA phase error\r\n");
}
return 0;
}
输出结果:
6
name:james type=4
age:20 type=3
pass:0.00 type=0
由于JSON结构体中存在字符串类型、浮点型和整型三种数据类型,为了方便用户处理,CJSON提供了cJSON_Print,统一将JSON解析的结果转换成字符串类型
int MyTest3()
{
char *str;
char *json_str;
cJSON *cjson_data;
json_str = "{ \
\"personA\":{\"name\":\"james\",\"sex\":\"boy\",\"age\":20}, \
\"personB\":{\"name\":\"joe\",\"sex\":\"girl\",\"age\":18} \
}";
int arr_size;
cjson_data = cJSON_Parse(json_str);//将json字符串转化成CJSON结构体类型的数据
if(!cjson_data)
{
printf("json phase error\r\n");
return;
}
printf("%d\r\n",cjson_data->type);
cJSON* personA = cJSON_GetObjectItem(cjson_data,"personA");;
//if(personA)printf("%s:%s\r\n",personA->string,personA->child->valuestring);
if(personA)
{
str = cJSON_Print(cJSON_GetObjectItem(personA,"name"));
if(str)printf("name:%s\r\n",str);
str = cJSON_Print(cJSON_GetObjectItem(personA,"sex"));
if(str)printf("sex:%s\r\n",str);
str = cJSON_Print(cJSON_GetObjectItem(personA,"age"));
if(str)printf("age:%s\r\n",str);
if(str)free(str);
}
else
{
printf("personA phase error\r\n");
}
return 0;
}
输出结果:
6
name:"james"
sex:"boy"
age:20
3.2、解析JSON数组
- cJSON_GetArraySize函数可以获取键值对中的数组,并返回数组个数,我们可以通过遍历数组查找数组中的对应元素内容;
int MyTest4()
{
char *str;
char *json_str;
cJSON *cjson_data;
json_str = "{\"list\":[{ \"name\":\"Tom\", \"age\":18, \"sex\":\"boy\" }, { \"name\":\"Jack\", \"age\":19, \"sex\":\"girl\"}]}";
int arr_size;
printf("%s\r\n",json_str);
cjson_data = cJSON_Parse(json_str);//将json字符串转化成CJSON结构体类型的数据
if(!cjson_data)
{
printf("json phase error\r\n");
return -1;
}
printf("%d\r\n",cjson_data->type);
cJSON *pArray = cJSON_GetObjectItem(cjson_data, "list");
if (NULL == pArray)
{
printf("not find stu_info\n");
goto err;
}
int i;
int iArraySize = cJSON_GetArraySize(pArray);
for (i = 0; i < iArraySize; i++)
{
printf("******** Stu[%d] info ********\n", i + 1);
cJSON *item = cJSON_GetArrayItem(pArray, i);
cJSON *pName = cJSON_GetObjectItem(item, "name");
printf("name [%s]\n", pName->valuestring);
cJSON *pAge = cJSON_GetObjectItem(item, "age");
printf("age [%d]\n", pAge->valueint);
cJSON *pSex = cJSON_GetObjectItem(item, "sex");
printf("sex [%s]\n", pSex->valuestring);
}
err:
cJSON_Delete(cjson_data);
return 0;
}
输出结果:
{"list":[{ "name":"Tom", "age":18, "sex":"boy" }, { "name":"Jack", "age":19, "sex":"girl"}]}
6
******** Stu[1] info ********
name [Tom]
age [18]
sex [boy]
******** Stu[2] info ********
name [Jack]
age [19]
sex [girl]
3.3、创建JSON数据
void create_obj_test1()
{
cJSON *root;
cJSON *fmt;
cJSON *img;
cJSON *thm;
int ids[4]={116,943,234,38793};
char *out;
root=cJSON_CreateObject();
cJSON_AddItemToObject(root, "Image", img=cJSON_CreateObject());
cJSON_AddNumberToObject(img,"Width",800);
cJSON_AddNumberToObject(img,"Height",600);
cJSON_AddStringToObject(img,"Title","View from 15th Floor");
cJSON_AddItemToObject(img, "Thumbnail", thm=cJSON_CreateObject());
cJSON_AddStringToObject(thm, "Url", "http:/*www.example.com/image/481989943");
cJSON_AddNumberToObject(thm,"Height",125);
cJSON_AddStringToObject(thm,"Width","100");
cJSON_AddItemToObject(img,"IDs", cJSON_CreateIntArray(ids,4));
out=cJSON_Print(root); cJSON_Delete(root); printf("%s\n",out); free(out);
}
输出结果:
{
"Image": {
"Width": 800,
"Height": 600,
"Title": "View from 15th Floor",
"Thumbnail": {
"Url": "http:/*www.example.com/image/481989943",
"Height": 125,
"Width": "100"
},
"IDs": [116, 943, 234, 38793]
}
}