JSON

JSON简介:


JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,可以把JSON的结构理解成无序的、可嵌套(指value可以再嵌套一层key-value)的key-value键值对集合,这些key-value键值对是以结构体或数组的形式来组织的。同一级的key-value键值对之间是用一个“,”(逗号)隔开,每个key-value键值对是由一个key后面紧接一个“:”(冒号),冒号后面是这个key对应的value。Key是一个word,由大小写字母、下划线及数字组成,可以由双引号封闭,也可以不加双引号;而value的取值集为:Number、Boolean(true或false)、null、String、Object及Array,如图一:


 
(图一)
 

1、Number:数值,包括整形数与浮点数,如:123、0.83、-2.7e10。其结构如图二:


(图二)


 

2、String:字符串,是以双引号封闭起来的一串字符,使用反斜杠来转义,如:\\、\n等,JSON中字符串的概念与C/C++或者JAVA语言里的字符串概念差不多,如:”abc”。其结构如图三:


(图三)

 

3、Object:对象,也可理解成一个结构体,是以一对大括号封闭起来的无序的key-value键值对集合,例如:{name:"Susan", age:27, birthday:{year:1984, month:2, day:11}};也可以写成:{"name":"Susan", "age":27, "birthday":{"year":1984, "month":2, "day":11}};其结构如图四:


(图四)

4、Array:数组,JSON的数组是一个以中括号封闭起来的value的集合,即数组内的各个成员的数据类型可以不一样,这一点就跟C/JAVA的数组概念不同了。每个value之间是由一个“,”(逗号)隔开,例如:[123, abc, false, {name:mj}];其结构如图五:

 
(图五)





 

cJSON:C语言的JSON解释器


在CJSON中,一个key-value键值对被解析并存放在一个cJSON结构体变量中,其value取值集为:FALSE,TRUE,NULL,NUMBER,STRING,OBJECT,ARRAY。

 
  1. #define     cJSON_False     0
  2. #define     cJSON_True      1
  3. #define     cJSON_NULL  2
  4. #define     cJSON_Number    3
  5. #define     cJSON_String    4
  6. #define     cJSON_Array     5
  7. #define     cJSON_Object    6

cJSON 结构体:

 
  1. typedef struct cJSON
  2. {
  3.     struct cJSON *next,*prev;   //指向上一项/下一项
  4.     struct cJSON *child;    //指向下一级,也就是当type为cJSON_Object或cJSON_Array时,此指针不为空。
  5.     int type;                   
  6.     char *valuestring;  // 当type为cJSON_String时
  7.     int valueint;       // 当 type为cJSON_Number时
  8.     double valuedouble; //当type为cJSON_Number时
  9.  
  10.     char *string;       // 当前项的名称,也就是key-value键值对的key
  11. } cJSON;

typedef struct cJSON {
 14         struct cJSON *next,*prev;       // next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/    GetObjectItem
 15         struct cJSON *child;                 // An array or object item will have a child pointer pointing to a chain of the items in the arra    y/object.                                                     int type;                                       // The type of the item, as above.
 18 
 19         char *valuestring;                      // The item's string, if type==cJSON_String
 20         int valueint;                           // The item's number, if type==cJSON_Number
 21         double valuedouble;                     // The item's number, if type==cJSON_Number
 22 
 23         char *string;                           // The item's name string (=key), if this item is the child of, or is in the list of subitems of an object.
 24 } cJSON; //并不存储Array/Object的名字


在解析JSON过程中,从JSON格式描述的value数据到CJSON对象中存放的变量的一个映射关系如图七:


(图七)


对JSON格式的解析是使用cJSON_Parse()方法,其传入的参数是一个JSON的Object/Array结构的字串解析成功则返回一个cJSON结构体变量的指针,在使用完成后需要调用cJSON_Delete()将该指针销毁。CJSON是以树状结构来组织内部的各个cJSON结构体变量的,一般地,要使用某个cJSON结构体变量,需要调用cJSON_GetObjectItem()方法并根据其父节点的cJSON结构体变量指针与该项的名称来获取其指针,举个例子: 

 

 
  1. bool bResult;
  2. char jsonString[] = “{result:true}”;
  3. //获取result的值true
  4. cJSON* pItem = NULL;
  5. cJSON* pRoot = cJSON_Parse ( jsonString );
  6. if ( pRoot )
  7. {
  8.     pItem = cJSON_GetObjectItem ( pRoot, “result” );
  9.     if ( pItem )
  10.     {
  11.         bResult = pItem->valueint;   //由于result的值type为cJSON_False或cJSON_True,所以其值被存放在valueint变量中
  12.     }
  13.     cJSON_Delete ( pRoot );
  14. }

 

在上例中,不管result的值type为何类型,都是通过调用cJSON_GetObjectItem()方法获取其对应的cJSON结构体变量的指针,只是在处理其对应的值时会有所不同。如果result的值type为cJSON_Object,则需要通过调用cJSON_GetObjectItem( pItem, “subItemKey”)来获取其子Item的指针。在处理值type为cJSON_Array的Item时,就需要再用到另外两个API:cJSON_GetArraySize ()和cJSON_GetArrayItem()。我们举个获取一个数组成员值的例子:

 
  1. charout;
  2. char jsonString[] = “{colors:[\“red\”, \“green\”,\ “blue\”, \“yellow\”, \“white\”]}”;
  3. cJSON* pArray = NULL;
  4. cJSON* pRoot = cJSON_Parse ( jsonString );
  5. if ( pRoot )
  6. {
  7.     pArray = cJSON_GetObjectItem ( pRoot, “colors” );
  8.     if ( pArray )
  9.     {
  10.         cJSON* pArrayItem = NULL;
  11.         int nCount = cJSON_GetArraySize ( pArray ); //获取pArray数组的大小
  12.         forint i = 0; i < nCount; i++)
  13.         {
  14.             pArrayItem = cJSON_GetArrayItem(pArray, i);
  15.             out = cJSON_Print( pArrayItem );    //将pArrayItem的值以字串的形式打印到char型buffer上,cJSON_Print()会自动分配内存空间,用完需要释放内存。
  16.             SS_printf( “array item %d: %s\n”, i, out);
  17.             Free( out );
  18.         }
  19.     }
  20.     cJSON_Delete ( pRoot );
  21. }

在提取一个复杂的JSON格式的数据时,也只是将以上两个例子使用到的方法进行组合调用罢了。所以对CJSON提供的API的使用是很简单有效的。有了以上知识的了解,我们就可以编写一些代码将例一中的JSON解析并提取其中的数据。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值