json格式解析和libjson的用法介绍(关于cjson的使用方法)分享!

cJSON Types:

  #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

cJSON 结构体:

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

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

(图七)

json格式解析和libjson的用法介绍(关于cjson的使用方法)

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

  bool bResult;    char jsonString[] = “{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;    char jsonString[] = “{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;        int nCount = cJSON_GetArraySize ( pArray ); //获取pArray数组的大小        for( int i = 0; i < nCount; i++)        {          pArrayItem = cJSON_GetArrayItem(pArray, i);          out = cJSON_Print( pArrayItem );  //将pArrayItem的值以字串的形式打印到char型buffer上,cJSON_Print()会自动分配内存空间,用完需要释放内存。          SS_printf( “array item %d: %sn”, i, out);          Free( out );        }      }      cJSON_Delete ( pRoot );    }

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

TChannelsData.h:

  /** 子频道信息结构体    *     */    struct SUBCHNL_DATA    {      SUBCHNL_DATA();      void clear();           TUChar * m_title;      char * m_link;      TUChar * m_desc;    };         /** 大频道信息结构体    *     */    struct CHANNEL_DATA    {      CHANNEL_DATA();           TUChar* m_pszTitle;      vector m_aSubChnlList;    };         //………….    // TChannelsData 类成员变量:RSSReaderConfig 版本号    char m_pszVersion[32];    // TChannelsData 类成员变量:频道信息列表    vector m_aChnlsList;    //………….    TChannelsData.cpp:        /** 解析JSON格式的内容    *     * param pszJsonText 解析的JSON格式内容字串    *     * return true:有更新数据; false:没有更新数据    */    Boolean TChannelsData::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)          {            return FALSE;          }        }        else        {          return FALSE;        }             //获取更新数据,根节点root        objRootItem = cJSON_GetObjectItem(objJson, "root");        if (objRootItem)        {          cJSON* objJsonItem = NULL;               //获取版本号          objJsonItem = cJSON_GetObjectItem(objRootItem, "version");          if (objJsonItem)          {            Int32 nLen = strlen(objJsonItem->valuestring);            strncpy(m_pszVersion, objJsonItem->valuestring, (nLen < 32)? nLen : 31);          }               //解析出大频道          _ParseChannels(objRootItem);        }                //SS_printf("=======[parse json]%sn",out);        cJSON_Delete(objJson);        //free(out);      }           return TRUE;    }         /** 解析出大频道    *     * param pCJson cJSON对象指针    *     * return void    */    void TChannelsData::_ParseChannels(cJSON* pCJson)    {      cJSON* pJsonArray = NULL;           if (!pCJson)      {        return;      }           pJsonArray = cJSON_GetObjectItem(pCJson, "channels");      if(pJsonArray)      {        cJSON* pArrayItem = NULL;        cJSON* pJsonTemp = NULL;             Int32 nSize = cJSON_GetArraySize(pJsonArray);        for (Int32 i = 0; i < nSize; i++)        {          pArrayItem = cJSON_GetArrayItem(pJsonArray, i);          if (pArrayItem)          {            CHANNEL_DATA tChannelData;            Int32 nLen = 0;                 //获取大频道名称            tChannelData.m_pszTitle = _JsonGetTUString(pArrayItem, "name");                        //解析出子频道            _ParseSubChnls(tChannelData.m_aSubChnlList, pArrayItem);                 //将大频道信息对象压入列表中            m_aChnlsList.push_back(tChannelData);          }          else          {            continue;          }        }      }    }         /** 解析子频道    *     * param aSubChnlList 存放子频道数据的vector对象    * param pCJson cJSON对象指针    *     * return void    */    void TChannelsData::_ParseSubChnls(vector& aSubChnlList, cJSON* pCJson)    {      cJSON* pJsonArray = NULL;           if (!pCJson)      {        return;      }           pJsonArray = cJSON_GetObjectItem(pCJson, "subchnls");      if (pJsonArray)      {        cJSON* pArrayItem = NULL;        //cJSON* pJsonTemp = NULL;             Int32 nSize = cJSON_GetArraySize(pJsonArray);        for (Int32 i = 0; i < nSize; i++)        {          pArrayItem = cJSON_GetArrayItem(pJsonArray, i);          if (pArrayItem)          {            SUBCHNL_DATA tSubChnlData;            Int32 nLen = 0;                 //get title            tSubChnlData.m_title = _JsonGetTUString(pArrayItem, "title");                 //get link            tSubChnlData.m_link = _JsonGetString(pArrayItem, "link");                 //get desc            tSubChnlData.m_desc = _JsonGetTUString(pArrayItem, "desc");                 aSubChnlList.push_back(tSubChnlData);          }        }      }    }         /** 获取指定的cJSON对象的指定属性值    *     * param pJsonItem cJSON对象指针    * param pszKey cJSON对象属性    *     * return 返回JSON对象的值,以TUChar字串形式返回    */    TUChar* TChannelsData::_JsonGetTUString(cJSON* pJsonItem, char* pszKey)    {      TUChar* pszValue = NULL;      Int32 nLen;      cJSON* pJsonTemp = NULL;           pJsonTemp = cJSON_GetObjectItem(pJsonItem, pszKey);      if (pJsonTemp)      {        nLen = strlen(pJsonTemp->valuestring) + 1;        pszValue = new TUChar[nLen];        if(pszValue)        {          MemSet(pszValue, 0, nLen * sizeof(TUChar));          TUString::StrUtf8ToStrUnicode(pszValue, (const Char*)pJsonTemp->valuestring);        }      }           return pszValue;    }         /** 获取指定的cJSON对象的指定属性值    *     * param pJsonItem cJSON对象指针    * param pszKey cJSON对象属性    *     * return 返回JSON对象的值,以char字串形式返回    */    char* TChannelsData::_JsonGetString(cJSON* pJsonItem, char* pszKey)    {      char* pszValue = NULL;      Int32 nLen;      cJSON* pJsonTemp = NULL;           pJsonTemp = cJSON_GetObjectItem(pJsonItem, pszKey);      if (pJsonTemp)      {        nLen = strlen(pJsonTemp->valuestring) + 1;        pszValue = new char[nLen];        if(pszValue)        {          MemSet(pszValue, 0, nLen);          strncpy(pszValue, pJsonTemp->valuestring, nLen - 1);        }      }           return pszValue;    }         /** 获取指定的cJSON对象的指定属性值    *     * param pJsonItem cJSON对象指针    * param pszKey cJSON对象属性    *     * return 返回JSON对象的值,以int32形式返回    */    Int32 TChannelsData::_JsonGetInt(cJSON* pJsonItem, char* pszKey)    {      Int32 nValue = 0;      cJSON* pJsonTemp = NULL;           pJsonTemp = cJSON_GetObjectItem(pJsonItem, pszKey);      if (pJsonTemp)      {        nValue = pJsonTemp->valueint;      }           return nValue;    }         /** 获取指定的cJSON对象的指定属性值    *     * param pJsonItem cJSON对象指针    * param pszKey cJSON对象属性    *     * return 返回JSON对象的值,以Boolean形式返回    */    Boolean TChannelsData::_JsonGetBoolean(cJSON* pJsonItem, char* pszKey)    {      Boolean bValue = FALSE;      cJSON* pJsonTemp = NULL;           pJsonTemp = cJSON_GetObjectItem(pJsonItem, pszKey);      if (pJsonTemp)      {        if(pJsonTemp->valueint)        {          bValue = TRUE;        }      }           return bValue;    }

总结:

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/481731.html

(0)
上一篇 2020年11月9日
下一篇 2020年11月9日

精彩推荐