Cjson的使用
cJSON简介: JSON(JavaScriptObject Notation)是一种轻量级的数据交换格式。它基于JavaScript的一个子集。JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。 cJSON是一个超轻巧,携带方便,单文件,简单的可以作为ANSI-C标准的JSON解析器。 cJSON结构体: typedefstruct cJSON { structcJSON *next,*prev; struct cJSON *child; int type; char * valuestring; int valueint; double valuedouble; char *string; }cJSON; 1、cJSON存储的时候是采用链表存储的,其访问方式很像一颗树。每一个节点可以有兄妹节点,通过next/prev指针来查找,它类似双向链表;每个节点也可以有孩子节点,通过child指针来访问,进入下一层。 不过,只有节点是对象或数组才可以有孩子节点。 2、type一共有7种取值,分别是: #define cJSON_False 0 #define cJSON_True 1 #define cJSON_NULL 2 #define cJSON_Number 3 #define cJSON_String 4 #define cJSON_Array 5 #define cJSON_Object 6 若是Number类型,则valueint或valuedouble中存储着值,若你期望的是int,则访问valueint,若期望的是double,则访问valuedouble,可以得到值。 若是String类型的,则valuestring中存储着值,可以访问valuestring得到值。 3、string中存放的是这个节点的名字。 用法: 1、只需在函数中includecJSON.h头文件,然后和cJSON.c或库文件libcJSON.a一起编译即可使用。 2、具体函数用法详见cJSON.h中注释 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- http://apps.hi.baidu.com/share/detail/42828576
JSON格式解析和libjson使用简介
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}];其结构如图五:
下面我们就来动手写一个例子: { result:true, root:{ version:"201007091640", channels:[ { name:"新闻中心", subchnls:[ { title:"焦点新闻", link:"http://news.mtc.sohu.com/news/channel/1/news.rss", desc:"家事、国事、天下事" }, { title:"新闻频道", link:"http://news.mtc.sohu.com/news/channel/2/news.rss", desc:"让您实时掌握国际动态" }, { title:"军事频道", link:"http://news.mtc.sohu.com/news/channel/3/news.rss", desc:"军事" } ] },
{ name:"体育新闻", subchnls:[ { title:"体育要闻汇总", link:"http://news.mtc.sohu.com/news/channel/4/news.rss", desc:"erewr" }, { title:"国际足坛", link:"http://news.mtc.sohu.com/news/channel/5/news.rss", desc:"werewr" } ] }
] } }
#definecJSON_False0 #definecJSON_True1 #definecJSON_NULL2 #definecJSON_Number3 #definecJSON_String4 #definecJSON_Array5 #definecJSON_Object6 cJSON结构体: typedefstructcJSON { structcJSON*next,*prev;//指向上一项/下一项 structcJSON*child;//指向下一级,也就是当type为cJSON_Object或cJSON_Array时,此指针不为空。 inttype; char*valuestring;//当type为cJSON_String时 intvalueint;//当type为cJSON_Number时 doublevaluedouble;//当type为cJSON_Number时 char*string;//当前项的名称,也就是key-value键值对的key }cJSON; 在解析JSON过程中,从JSON格式描述的value数据到CJSON对象中存放的变量的一个映射关系如图七:
boolbResult; charjsonString[]=“{result:true}”; //获取result的值true cJSON*pItem=NULL; cJSON*pRoot=cJSON_Parse(jsonString); if(pRoot) { pItem=cJSON_GetObjectItem(pRoot,“result”); if(pItem) { bResult=pItem->valueint;//由于result的值type为cJSON_False或cJSON_True,所以其值被存放在valueint变量中 } cJSON_Delete(pRoot); } 在上例中,不管result的值type为何类型,都是通过调用cJSON_GetObjectItem()方法获取其对应的cJSON结构体变量的指针,只是在处理其对应的值时会有所不同。如果result的值type为cJSON_Object,则需要通过调用cJSON_GetObjectItem(pItem,“subItemKey”)来获取其子Item的指针。在处理值type为cJSON_Array的Item时,就需要再用到另外两个API:cJSON_GetArraySize()和cJSON_GetArrayItem()。我们举个获取一个数组成员值的例子: char*out; charjsonString[]=“{colors:[“red”,“green”,“blue”,“yellow”,“white”]}”; cJSON*pArray=NULL; cJSON*pRoot=cJSON_Parse(jsonString); if(pRoot) { pArray=cJSON_GetObjectItem(pRoot,“colors”); if(pArray) { cJSON*pArrayItem=NULL; intnCount=cJSON_GetArraySize(pArray);//获取pArray数组的大小 for(inti=0;i<nCount;i++) { pArrayItem=cJSON_GetArrayItem(pArray,i); out=cJSON_Print(pArrayItem);//将pArrayItem的值以字串的形式打印到char型buffer上,cJSON_Print()会自动分配内存空间,用完需要释放内存。 SS_printf(“arrayitem%d:%sn”,i,out); Free(out); } } cJSON_Delete(pRoot); } 在提取一个复杂的JSON格式的数据时,也只是将以上两个例子使用到的方法进行组合调用罢了。所以对CJSON提供的API的使用是很简单有效的。有了以上知识的了解,我们就可以编写一些代码将例一中的JSON解析并提取其中的数据,还是贴点代码才是硬道理,代码如下: TChannelsData.h: /**子频道信息结构体 * */ structSUBCHNL_DATA { SUBCHNL_DATA(); voidclear(); TUChar*m_title; char*m_link; TUChar*m_desc; }; /**大频道信息结构体 * */ structCHANNEL_DATA { CHANNEL_DATA(); TUChar*m_pszTitle; vectorm_aSubChnlList; }; //…………. //TChannelsData类成员变量:RSSReaderConfig版本号 charm_pszVersion[32]; //TChannelsData类成员变量:频道信息列表 vectorm_aChnlsList; //…………. TChannelsData.cpp: /**解析JSON格式的内容 * *parampszJsonText解析的JSON格式内容字串 * *returntrue:有更新数据;false:没有更新数据 */ BooleanTChannelsData::ParseJson(char*pszJsonText) { //char*out; cJSON*objJson; objJson=cJSON_Parse(pszJsonText); if(objJson) { //out=cJSON_Print(objJson); cJSON*objRootItem=NULL; //判断是否需要更新 objRootItem=cJSON_GetObjectItem(objJson,"result"); if(objRootItem) { if(!objRootItem->valueint) { returnFALSE; } } else { returnFALSE; } //获取更新数据,根节点root objRootItem=cJSON_GetObjectItem(objJson,"root"); if(objRootItem) { cJSON*objJsonItem=NULL; //获取版本号 objJsonItem=cJSON_GetObjectItem(objRootItem,"version"); if(objJsonItem) { Int32nLen=strlen(objJsonItem->valuestring); strncpy(m_pszVersion,objJsonItem->valuestring,(nLen<32)?nLen:31); } //解析出大频道 _ParseChannels(objRootItem); }
//SS_printf("=======[parsejson]%sn",out); cJSON_Delete(objJson); //free(out); } returnTRUE; } /**解析出大频道 * *parampCJsoncJSON对象指针 * *returnvoid */ voidTChannelsData::_ParseChannels(cJSON*pCJson) { cJSON*pJsonArray=NULL; if(!pCJson) { return; } pJsonArray=cJSON_GetObjectItem(pCJson,"channels"); if(pJsonArray) { cJSON*pArrayItem=NULL; cJSON*pJsonTemp=NULL; Int32nSize=cJSON_GetArraySize(pJsonArray); for(Int32i=0;i<nSize;i++) { pArrayItem=cJSON_GetArrayItem(pJsonArray,i); if(pArrayItem) { CHANNEL_DATAtChannelData; Int32nLen=0; //获取大频道名称 tChannelData.m_pszTitle=_JsonGetTUString(pArrayItem,"name");
//解析出子频道 _ParseSubChnls(tChannelData.m_aSubChnlList,pArrayItem); //将大频道信息对象压入列表中 m_aChnlsList.push_back(tChannelData); } else { continue; } } } } /**解析子频道 * *paramaSubChnlList存放子频道数据的vector对象 *parampCJsoncJSON对象指针 * *returnvoid */ voidTChannelsData::_ParseSubChnls(vector&aSubChnlList,cJSON*pCJson) { cJSON*pJsonArray=NULL; if(!pCJson) { return; } pJsonArray=cJSON_GetObjectItem(pCJson,"subchnls"); if(pJsonArray) { cJSON*pArrayItem=NULL; //cJSON*pJsonTemp=NULL; Int32nSize=cJSON_GetArraySize(pJsonArray); for(Int32i=0;i<nSize;i++) { pArrayItem=cJSON_GetArrayItem(pJsonArray,i); if(pArrayItem) { SUBCHNL_DATAtSubChnlData; Int32nLen=0; //gettitle tSubChnlData.m_title=_JsonGetTUString(pArrayItem,"title"); //getlink tSubChnlData.m_link=_JsonGetString(pArrayItem,"link"); //getdesc tSubChnlData.m_desc=_JsonGetTUString(pArrayItem,"desc"); aSubChnlList.push_back(tSubChnlData); } } } } /**获取指定的cJSON对象的指定属性值 * *parampJsonItemcJSON对象指针 *parampszKeycJSON对象属性 * *return返回JSON对象的值,以TUChar字串形式返回 */ TUChar*TChannelsData::_JsonGetTUString(cJSON*pJsonItem,char*pszKey) { TUChar*pszValue=NULL; Int32nLen; cJSON*pJsonTemp=NULL; pJsonTemp=cJSON_GetObjectItem(pJsonItem,pszKey); if(pJsonTemp) { nLen=strlen(pJsonTemp->valuestring)+1; pszValue=newTUChar[nLen]; if(pszValue) { MemSet(pszValue,nLen*sizeof(TUChar)); TUString::StrUtf8ToStrUnicode(pszValue,(constChar*)pJsonTemp->valuestring); } } returnpszValue; } /**获取指定的cJSON对象的指定属性值 * *parampJsonItemcJSON对象指针 *parampszKeycJSON对象属性 * *return返回JSON对象的值,以char字串形式返回 */ char*TChannelsData::_JsonGetString(cJSON*pJsonItem,char*pszKey) { char*pszValue=NULL; Int32nLen; cJSON*pJsonTemp=NULL; pJsonTemp=cJSON_GetObjectItem(pJsonItem,pszKey); if(pJsonTemp) { nLen=strlen(pJsonTemp->valuestring)+1; pszValue=newchar[nLen]; if(pszValue) { MemSet(pszValue,nLen); strncpy(pszValue,pJsonTemp->valuestring,nLen-1); } } returnpszValue; } /**获取指定的cJSON对象的指定属性值 * *parampJsonItemcJSON对象指针 *parampszKeycJSON对象属性 * *return返回JSON对象的值,以int32形式返回 */ Int32TChannelsData::_JsonGetInt(cJSON*pJsonItem,char*pszKey) { Int32nValue=0; cJSON*pJsonTemp=NULL; pJsonTemp=cJSON_GetObjectItem(pJsonItem,pszKey); if(pJsonTemp) { nValue=pJsonTemp->valueint; } returnnValue; } /**获取指定的cJSON对象的指定属性值 * *parampJsonItemcJSON对象指针 *parampszKeycJSON对象属性 * *return返回JSON对象的值,以Boolean形式返回 */ BooleanTChannelsData::_JsonGetBoolean(cJSON*pJsonItem,char*pszKey) { BooleanbValue=FALSE; cJSON*pJsonTemp=NULL; pJsonTemp=cJSON_GetObjectItem(pJsonItem,pszKey); if(pJsonTemp) { if(pJsonTemp->valueint) { bValue=TRUE; } } returnbValue; } JSON的结构简约,所以使得JSON的文档的数据量比较小,比较适合用于网络数据的交换,而且对JSON文档的解析和数据提取的方法也很简单,方便程序员的使用,当然也正是因为JSON的结构简约,使得JSON的可读性与可编辑性会稍差于XML,所以JSON比较适合在较少有人工阅读和编辑的情况下使用期。
备注:经验证名称需加“比如charjsonString[]="{"result":true}"; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |