JSON是一種輕量級(jí)的數(shù)據(jù)交互格式,其不僅易于閱讀和編寫,還是現(xiàn)代應(yīng)用程序所采用的主流數(shù)據(jù)格式之一。在C語言中,我們可以使用cJSON庫來解析和生成JSON數(shù)據(jù)。而對(duì)于多層JSON數(shù)據(jù)的處理,cJSON也提供了相應(yīng)的接口。
多層JSON數(shù)據(jù)的處理需要我們了解JSON對(duì)象的嵌套結(jié)構(gòu)。在cJSON庫中,每一個(gè)JSON對(duì)象都由cJSON結(jié)構(gòu)體表示。cJSON結(jié)構(gòu)體定義如下:
typedef struct cJSON { struct cJSON *next, *prev; struct cJSON *child; int type; char *valuestring; int valueint; double valuedouble; char *string; } cJSON;
其中,next和prev指針用于連接兄弟節(jié)點(diǎn),child指針用于連接子節(jié)點(diǎn)。我們可以通過遞歸遍歷子節(jié)點(diǎn),來處理多層JSON數(shù)據(jù)。
下面是一個(gè)處理多層JSON數(shù)據(jù)的示例代碼:
#include "cJSON.h" #include <stdio.h> void parse_json(cJSON *root) { if (!root) { return; } cJSON *p = root->child; while (p) { if (p->type == cJSON_Object) { printf("Object: %s\n", p->string); parse_json(p); } else if (p->type == cJSON_Array) { printf("Array: %s\n", p->string); int size = cJSON_GetArraySize(p); for (int i = 0; i< size; i++) { cJSON *q = cJSON_GetArrayItem(p, i); parse_json(q); } } else { printf("Value: %s=%d\n", p->string, p->valueint); } p = p->next; } } int main() { char json_str[] = "{" " \"name\": \"John\"," " \"age\": 30," " \"address\": {" " \"city\": \"Beijing\"," " \"country\": \"China\"" " }," " \"phones\": [" " {" " \"type\": \"home\"," " \"number\": \"123456789\"" " }," " {" " \"type\": \"work\"," " \"number\": \"987654321\"" " }" " ]" "}"; cJSON *root = cJSON_Parse(json_str); if (!root) { printf("parse json error\n"); return 0; } parse_json(root); cJSON_Delete(root); return 0; }
在上面的代碼中,解析出來的JSON數(shù)據(jù)包含了兩個(gè)Object類型的節(jié)點(diǎn)和一個(gè)Array類型的節(jié)點(diǎn)。我們使用parse_json函數(shù)來遍歷子節(jié)點(diǎn),并根據(jù)不同的節(jié)點(diǎn)類型進(jìn)行處理。如果是Object類型的節(jié)點(diǎn),則遞歸遍歷其子節(jié)點(diǎn);如果是Array類型的節(jié)點(diǎn),則循環(huán)遍歷其子節(jié)點(diǎn);如果是Value類型的節(jié)點(diǎn),則直接輸出其值。
綜上,使用cJSON庫處理多層JSON數(shù)據(jù),需要了解JSON對(duì)象的嵌套結(jié)構(gòu),并遞歸遍歷子節(jié)點(diǎn)進(jìn)行處理。