6.需要澄清的问题
1)cJSON无法区分Object还是Array,它只能通过cJSON中的type字段做区分,这种源码中更能明显看出
2)对外提供的几个接口
/* Get Array size/item / object item. */
int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
返回的cJSON指针,我们无须再释放;同时
cJSON_GetArraySize返回的是当前子对象数组的大小,如果还有更深的嵌套层次,不考虑;
cJSON_GetArrayItem返回的是下一级子数组中,第item个子数组所在的cJSON对象;
cJSON_GetObjectItem返回的是下一级子对象数组中,名为string的那个子cJSON对象;
如果我们想找第3层的某个名为string的对象,那只能一层一层的遍历,逐层查找,所以有时候不是很方便,具体做法如
cJSON *format = cJSON_GetObjectItem(root,"format");
int framerate = cJSON_GetObjectItem(format,"frame rate")->valueint;
为此,我们写如下函数,去递归查找指定名称的子对象
cJSON* find_Object(cJSON* object, const char* key){
cJSON* subitem = object->child;
while(subitem){
//忽略大小写进行比较
if(!strcasecmp(subitem->string,key))
return subitem;
//有子节点就优先查找子节点
cJSON* tmp = NULL;
if(subitem->child)
tmp = find_Object(subitem,key);
if(tmp) return tmp;
//如果子节点没有找到,返回在本层级查找
subitem = subitem->next;
}
return subitem;
}
3)修改某个子对象的stringvalue值,恐怕不能直接象修改整数的值这样做吧,因为字符串长度会有变化的,而该对象的内存事先已经分配好了
This is an object. We're in C. We don't have objects. But we do have structs.What's the framerate?
cJSON *format = cJSON_GetObjectItem(root,"format");
int framerate = cJSON_GetObjectItem(format,"frame rate")->valueint;
Want to change the framerate?
cJSON_GetObjectItem(format,"frame rate")->valueint=25;
对象的valuestring和string不能修改,只能直接获取,不需要删除,比如
void dump_level_1(cJSON* item){
int i;
for(i=0;i<cJSON_GetArraySize(item);i++){
cJSON* subitem = cJSON_GetArrayItem(item,i);
//这里只能拿到subitem->string,另一个值为空,注意这种方法获取的都是没有双引号的
printf("%s: %s\n",subitem->string,subitem->valuestring);
}
}
另外可参见
用C语言玩JSON http://www.linuxidc.com/Linux/2014-05/101823.htm
本文永久更新链接地址:http://www.linuxidc.com/Linux/2014-05/101822.htm