标签 json 下的文章

“”

解析一个键值对
首先是一个简单的键值对字符串,要解析的目标如下:

{"firstName":"Brett"}

要进行解析,也就是要分别获取到键与值的内容。我们很容易就能看出键为firstName,值为Brett,可是,使用cJSON怎么解析呢? 对于这个简单的例子,只需要调用cJSON的三个接口函数就可以实现解析了,这三个函数的原型如下:

cJSON*cJSON_Parse(const char *value); 
cJSON*cJSON_GetObjectItem(cJSON *object,const char *string);
voidcJSON_Delete(cJSON *c); 

下面按解析过程来描述一次:

首先调用cJSON_Parse()函数,解析JSON数据包,并按照cJSON结构体的结构序列化整个数据包。使用该函数会通过malloc()函数在内存中开辟一个空间,使用完成需要手动释放。

cJSON*root=cJSON_Parse(json_string); 

调用cJSON_GetObjectItem()函数,可从cJSON结构体中查找某个子节点名称(键名称),如果查找成功可把该子节点序列化到cJSON结构体中。

cJSON*item=cJSON_GetObjectItem(root,"firstName"); 

如果需要使用cJSON结构体中的内容,可通过cJSON结构体中的valueint和valuestring取出有价值的内容(即键的值)

本例子中,我们直接访问 item->valuestring 就获取到 "Brett" 的内容了。
通过cJSON_Delete(),释放cJSON_Parse()分配出来的内存空间。

cJSON_Delete(root);

这样就完成了一次cJSON接口调用,实现了解析工作。使用起来其实也很简单的啊,呵呵。

解析一个结构体
接下来,我们来个复杂一点的,解析一个结构体,要解析的目标如下:

{
         "person":
         {
                   "firstName":"z",
                   "lastName":"jadena",
                   "email":"jadena@126.com",
                   "age":8,
                   "height":1.17
         }        
}

看起来比一个键值对复杂多了,我们又需要学习新的接口函数了吗?还是那三个函数就可以了。当然,解析的步骤要复杂一些了,下面我按解析过程来描述一次:

根据JSON串中的对象,我们定义一个相应的结构体如下:

typedef struct
{
         char firstName[32];
         char lastName[32];
         char email[64];
         int age;
         float height;
} PERSON;

具体的对应关系,一目了然,我就不罗嗦了。让我们直奔主题,解析!

还是调用cJSON_Parse()函数,解析JSON数据包。

cJSON*root=cJSON_Parse(json_string);

调用一次cJSON_GetObjectItem()函数,获取到对象person。

cJSON *object=cJSON_GetObjectItem(root,"person");

对我们刚取出来的对象person,多次调用cJSON_GetObjectItem()函数,来获取对象的成员。此时要注意,不同的成员,访问的方法不一样:

cJSON* item;
PERSON person;
item=cJSON_GetObjectItem(object,"firstName");
memcpy(person.firstName,item->valuestring,strlen(item->valuestring));
item=cJSON_GetObjectItem(object,"lastName");
memcpy(person.lastName,item->valuestring,strlen(item->valuestring));
item=cJSON_GetObjectItem(object,"email");
memcpy(person.email,item->valuestring,strlen(item->valuestring));
item=cJSON_GetObjectItem(object,"age");
person.age=item->valueint;
item=cJSON_GetObjectItem(object,"height");
person.height=item->valuedouble;

这样,就获取到了对象的全部内容了。

通过cJSON_Delete(),释放cJSON_Parse()分配出来的内存空间。

cJSON_Delete(root);

至此,我们就使用cJSON接口完成了基于结构体的解析工作。

解析结构体数组的JSON串
最后,我们来个更复杂一些的,来解析一个数组,并且数组的成员是结构体!要解析的JSON串如下:

{
"people":[
{"firstName":"z","lastName":"Jason","email":"bbbb@126.com","height":1.67},
{"lastName":"jadena","email":"jadena@126.com","age":8,"height":1.17},
{"email":"cccc@126.com","firstName":"z","lastName":"Juliet","age":36,"height":1.55}
]
} 

此时,我们真的又需要学习新的接口了,一个是获取数组长度,一个是取数组成员,函数原型如下:

int    cJSON_GetArraySize(cJSON *array);
cJSON*cJSON_GetArrayItem(cJSON *array,int item);

由于前面已经实现了结构体的解析,这里我们只需要关注下数组的相关调用即可。

调用cJSON_Parse()函数,解析JSON数据包。

调用一次cJSON_GetObjectItem()函数,获取到数组people。

对我们刚取出来的数组people,调用cJSON_GetArraySize()函数,来获取数组中对象的个数。然后,多次调用cJSON_GetArrayItem()函数,逐个读取数组中对象的内容。

通过cJSON_Delete(),释放cJSON_Parse()分配出来的内存空间。

调用cJSON_Print(以及cJSON_PrintUnformatted)后,必须自行释放内存,对于1.5版本及以上的cJSON可以使用cJSON_free函数,其他版本直接使用free也可.
对于cJSON_Create..形式的函数,需要使用cJSON_Delete函数释放内存.
如果你把一个item添加到一个数组或者object里,不能直接释放item,因为它已经包含在被添加到数组或者object里了,删除数组或object时被添加的item同时也会被删除。

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "./cjson/cJSON.h"
 
/*
    注意:
        通过cJSON_PrintUnformatted(),cJSON_Print()函数返回的字符串需要手动free(释放空间)
        cJSON_CreateObject()函数创造的数据不使用时需要使用cJSON_Delete()释放空间
*/
 
 
/*cJSON的基本封装*/
cJSON *basic_cjson_pkg(void)
{
    cJSON *root = cJSON_CreateObject();
    if (NULL == root) {
        return NULL;
    }
    cJSON_AddNumberToObject(root, "action", 666); 
    cJSON *data = cJSON_CreateObject();
    if (NULL == data) {
        goto err1;
    }
    cJSON_AddStringToObject(data, "user", "Sky.J");
    cJSON_AddStringToObject(data, "pwd", "123456");
    cJSON_AddItemToObject(root, "data", data);
    return root;
err1:
    cJSON_Delete(root);
    return NULL;
}
 
/*cJSON的基本解析*/
void basic_cjson_sys(cJSON *root)
{
    if (NULL == root) {
        return ;
    }
    //将json包转为字符串显示,一般我们使用时选择str1,str2这种方式是更加容易我们观看的方式
    char *str1 = cJSON_PrintUnformatted(root);
    char *str2 = cJSON_Print(root);
    printf("str1: \r\n%s\r\n", str1);
    printf("str2: \r\n%s\r\n", str2);
    cJSON_Delete(root);
    free(str2);
    //一般我们接收到的也是cjson类型的字符串str1,下面解析
    //将字符串格式cjson数据转为cJSON类型数据
    cJSON *sys_root = cJSON_Parse(str1);
    if (NULL == sys_root) {
        goto err1;
    }
    cJSON *action = cJSON_GetObjectItem(sys_root, "action");
    if (NULL == action) {
        goto err2;
    }
    int action_value = action->valueint;
    
    cJSON *data = cJSON_GetObjectItem(sys_root, "data");
    if (NULL == data) {
        goto err2;
    }
    
    cJSON *user = cJSON_GetObjectItem(data, "user");
    if (NULL == user) {
        goto err2;
    }
    char *user_value = user->valuestring;
    
    cJSON *pwd = cJSON_GetObjectItem(data, "pwd");
    if (NULL == pwd) {
        goto err2;
    }
    char *pwd_value = pwd->valuestring;
    
    printf("action = %d, user = %s, pwd = %s\r\n", action_value, user_value, pwd_value);
err2:
    cJSON_Delete(sys_root);
err1:
    free(str1);
    return ;
}
 
/*cJSON的数组封装*/
cJSON *array_cjson_pkg(void)
{
    int i;
    char buffer[20];
    cJSON *root = cJSON_CreateObject();
    if (NULL == root) {
        return NULL;
    }
    cJSON_AddNumberToObject(root, "action", 888); 
    cJSON *data = cJSON_CreateObject();
    if (NULL == data) {
        goto err1;
    }
    cJSON_AddItemToObject(root, "data", data);
    cJSON *rows = cJSON_CreateArray();
    if (NULL == rows) {
        goto err1;
    }
    cJSON_AddItemToObject(data, "rows", rows);
    for (i = 0; i < 3; i++) {
        memset(buffer, 0, sizeof(buffer));
        snprintf(buffer, sizeof(buffer), "user%d", i);
        cJSON *row = cJSON_CreateObject();
        if (NULL == row) {
            goto err1;
        }
        //将新建项目插入数组中
        cJSON_AddItemToArray(rows, row);
        //添加详细信息
        cJSON_AddStringToObject(row, "user", buffer);
        cJSON_AddStringToObject(row, "pwd", "123456");
    }
    return root;
err1:
    cJSON_Delete(root);
    return NULL;
}
 
/*cJSON的数组解析*/
void array_cjson_sys(cJSON *root)
{
    if (NULL == root) {
        return ;
    }
    //将json包转为字符串显示,一般我们使用时选择str1,str2这种方式是更加容易我们观看的方式
    char *str1 = cJSON_PrintUnformatted(root);
    char *str2 = cJSON_Print(root);
    printf("str1: \r\n%s\r\n\r\n", str1);
    printf("str2: \r\n%s\r\n\r\n", str2);
    cJSON_Delete(root);
    free(str2);
    //一般我们接收到的也是cjson类型的字符串str1,下面解析
    //将字符串格式cjson数据转为cJSON类型数据
    cJSON *sys_root = cJSON_Parse(str1);
    if (NULL == sys_root) {
        goto err1;
    }
    cJSON *action = cJSON_GetObjectItem(sys_root, "action");
    if (NULL == action) {
        goto err2;
    }
    int action_value = action->valueint;
    
    cJSON *data = cJSON_GetObjectItem(root, "data");
    if (NULL == data) {
        goto err2;
    }
    //解析数组
    cJSON *rows = cJSON_GetObjectItem(data, "rows");
    if (NULL == rows) {
        goto err2;
    }
    int array_cnt = cJSON_GetArraySize(rows);
    printf("\r\naction = %d, array_cnt = %d\r\n", action_value, array_cnt);
    int i;
    for (i = 0; i < array_cnt; i ++) {
        //取出单个数组
        cJSON *row = cJSON_GetArrayItem(rows, i);
        if (NULL == row) {
            goto err2;
        }
        cJSON *user = cJSON_GetObjectItem(row, "user");
        if (NULL == user) {
            goto err2;
        }
        cJSON *pwd = cJSON_GetObjectItem(row, "pwd");
        if (NULL == pwd) {
            goto err2;
        }
        printf("user: %s, pwd: %s\r\n", user->valuestring, pwd->valuestring);
    }
err2:
    cJSON_Delete(sys_root);
err1:
    free(str1);
    return ;
}
 
 
 
int main()
{
    #if 1
    cJSON *root = basic_cjson_pkg();
    basic_cjson_sys(root);
    #else
    cJSON *root = array_cjson_pkg();
    array_cjson_sys(root);
    #endif
    return 0;
}

使用root = cJSON_Parse(text);

//将字符串转成json格式,函数中申请了一块内存给root  所以在最后要释放root

cJSON_Delete(root ); //释放cJSON_Parse()分配出来的内存空间

使用out = cJSON_Print(root);(含有cJSON_PrintUnformatted函数)

//函数将json数据转成字符串,这个函数内申请了一段内存给out,所以使用完out后也要释放

由于out不是json指针的数据格式,使用cJSON_free(out);释放即可

使用cJSON new_json_str = cJSON_Create*(str);

//将一个字符串转成一个json对象,函数里面也涉及了内存分配,用完以后也要释放cJSON_Delete(new_json_str );

若cJSON new_json = cJSON_Create*(str)创建后,通过cJSON_AddItemToObject( json, "test", new_json );(或者cJSON_AddItemToArray),加入到数组或者object中,不需要单独释放new_json ,删除json时被添加的item(此处为申请的new_json)同时也会被删除。

注意:cJSON_Delete( ) ,cJSON_free ( ) 要区分使用,json格式的使用cJSON_Delete  ,指针格式使用cJSON_free,对应关系如下:               

申请内存: cJSON_Parse cJSON_Create  cJSON_Print
释放内存: cJSON_Delete  cJSON_Delete  cJSON_free
Referenced from:https://blog.csdn.net/u013564851/article/details/107221600

c - Converting cjson json to string 
try cJSON_PrintUnformatted. cJSON_Print will print with whitespace for formatting. If you want to print without formatting, use cJSON_PrintUnformatted.
cJSON_Print will give you "{\n\t\"type1\":\t\"car\",\n\t\"type2\":\t\"bus\"\n}"

Referenced from:https://stackoverflow.com/questions/56073560/converting-cjson-json-to-string
cJSON_Print会得到这样的结果:

"{\n\t\"type1\":\t\"car\",\n\t\"type2\":\t\"bus\"\n}"

cJSON_PrintUnformatted会得到如下结果

"{\"type1\":\"car\",\"type2\":\"bus\"}"

注意,要使用cJSON_free释放字符串指针。

要读取网页上一个json内的数据内容,先将json内容保存为了多个json文件,然后将json字段提取出来保存在其他文件里面。

<?php
if(0)
{
 $prefix="rd";      
 $jsonfile = "rd-1.json,rd-2.json";
}
else
{
 $prefix="all"; 
 $jsonfile = "all-1.json,all-2.json,all-3.json,all-4.json,all-5.json,all-6.json,all-7.json,all-8.json";
}
$file = $prefix."-".date('Ymd').".txt"; 
$arr = explode(',', $jsonfile);
for($idx=0;$idx<count($arr);$idx++)
{
    $json=file_get_contents($arr[$idx]);
    $J=json_decode($json);   
    echo "通过下面的信息就可以获取里面的信息了</br>";  
    print_r($J);   
    printf(count($J->Data->users));
    for($i=0;$i<count($J->Data->users);$i++)
    {
        print_r($J->Data->users[$i]->name."\r\n"); 
        file_put_contents($file,$J->Data->users[$i]->name."\r\n", FILE_APPEND);
        
    }  
}
?> 

php 提取json字段 参考了下面这个

<?php   
$json=  
'{  
"item1":  
{"item11":{"n":"chenling","m":"llll"},"sex":"男","age":"25"},  
"item2":  
{"item21":"ling","sex":"女","age":"24"}  
}';    
$J=json_decode($json);   
echo "通过下面的信息就可以获取里面的信息了</br>";  
print_r($J);  
print_r("</br>");  
echo "测试访问对象内元素</br>";  
print_r($J->item1->item11->n."</br>");   
print_r($J->item1->sex."</br>");   
//注意不是标准的json  
print_r($J->item2->age."</br>");   
?>  

Referenced from:https://blog.csdn.net/zhoushengbin3/article/details/8174123
php 提取json字段 搜索到了下面这个

<?php
    $json = '{"state":"1","info":"登录成功"}';
    $arr = (array) json_decode($json,true);
    echo '状态码:'. $arr['state'];
 
    $json2 = '{"data":{"date":"2019-02-09","team":"第二学期"}}';
    $arr2 = (array) json_decode($json,true);
    echo '日期:'. $arr2['data']['date'].'学期:'.$arr2['data']['team'];
?>

Referenced from:https://blog.csdn.net/qq_17497931/article/details/87733372