2013-06-03 6 views
10

मैं cJSON पुस्तकालय, डेव गैंबल, द्वारा लिखित उपयोग करने के लिए निम्नलिखित JSON सारणी में पढ़ने का प्रयास कर रहा हूँ: पढ़ने सेएक JSON सरणी में पढ़ने के लिए cJSON का उपयोग

"items": 
[ 
    { 
     "name": "command", 
     "index": "X", 
     "optional": "0" 
    }, 
    { 
     "name": "status", 
     "index": "X", 
     "optional": "0" 
    } 
] 

उसकी documentation, मैं पढ़ने के लिए तरीके व्यक्तिगत वस्तुओं में, लेकिन Arrays के बारे में कुछ नहीं, और मैं यह अनुमान लगाने में सक्षम नहीं था कि दिए गए उदाहरणों से इसे कैसे किया जाए।

यहाँ मैं क्या कोशिश कर रहा हूँ है:

cJSON* request_json = NULL; 
cJSON* items = cJSON_CreateArray(); 
cJSON* name = NULL; 
cJSON* index = NULL; 
cJSON* optional = NULL; 

request_json = cJSON_Parse(request_body); 

items = cJSON_GetObjectItem(request_json, "items"); 

name = cJSON_GetObjectItem(items, "name"); 
index = cJSON_GetObjectItem(items, "index"); 
optional = cJSON_GetObjectItem(items, "optional"); 

मैं जानता हूँ कि यह गलत है, और न सिर्फ इसलिए कि यह काम नहीं कर रहा है, लेकिन मैं समझ नहीं कैसे यह सही बनाने के लिए।

स्पष्ट रूप से मुझे सरणी के प्रत्येक अनुक्रमणिका के लिए सभी प्रविष्टियों में पढ़ने की प्रक्रिया को लूप करने की आवश्यकता होगी। मुझे नहीं पता कि मैं ऐसा कैसे करने जा रहा हूं, क्योंकि मुझे नहीं पता कि मुझे इस कोड में इंडेक्स का उपयोग क्यों करना चाहिए, या यदि यह सही शुरुआत भी है। cJSON_GetArrayItem() है, लेकिन इसमें केवल एक संख्या (संभवतः एक सूचकांक) होती है और यह कोई संकेत नहीं देता है कि यह कौन सा फ़ील्ड चाहता है।

+0

तो "आइटम" का मूल्य एक सरणी है, यह मेरे लिए तुम वहाँ कहीं में एक सरणी का अनुक्रमण किया जाना चाहिए लगता है। फिर वह आपको "ऑब्जेक्ट" वापस देगा जो आप कुंजी द्वारा खोज सकते हैं। –

+0

(ध्यान दें कि जब आपने JSON उद्धृत किया है तो आपने आसपास के '{}' को गलती से छोड़ा है। '{} 'एक वस्तु" को इंगित करता है, और इसके बिना उपरोक्त पाठ अमान्य JSON है।) –

+0

यह नहीं था कि यह कैसे परिभाषित किया गया था कंपाइलर में, बस इसे उदाहरण के रूप में दिखा रहा है – Nealon

उत्तर

19

दस्तावेज़ parse_object() के बारे में बताता है।

मुझे लगता है कि आपको यही करना है।

void parse_object(cJSON *root) 
{ 
    cJSON* name = NULL; 
    cJSON* index = NULL; 
    cJSON* optional = NULL; 

    int i; 

    cJSON *item = cJSON_GetObjectItem(items,"items"); 
    for (i = 0 ; i < cJSON_GetArraySize(item) ; i++) 
    { 
    cJSON * subitem = cJSON_GetArrayItem(item, i); 
    name = cJSON_GetObjectItem(subitem, "name"); 
    index = cJSON_GetObjectItem(subitem, "index"); 
    optional = cJSON_GetObjectItem(subitem, "optional"); 
    } 
} 

कॉल के रूप में

request_json = cJSON_Parse(request_body); 
parse_object(request_json); 
+0

साइड नोट: संरचना में मूल्यों को संग्रहीत करना मेरे लिए सबसे अच्छा काम करता है। – Nealon

1

मेरा अनुमान इस समारोह (कल्पना पढ़ नहीं है, और सी के साथ एक सा जंग लगी जा रहा है):

request_json = cJSON_Parse(request_body); 

items = cJSON_GetObjectItem(request_json, "items"); 
for (int i = 0; i < max; i++) { // Presumably "max" can be derived from "items" somehow 

    cJSON* item = cJSON_GetArrayItem(items, i); 

    name = cJSON_GetObjectItem(item, "name"); 
    index = cJSON_GetObjectItem(item, "index"); 
    optional = cJSON_GetObjectItem(item, "optional"); 

    // Stash above info somewhere 
} 
+0

मैंने कल इसी तरह से संरचित इनपुट के साथ सीजेएसओएन का उपयोग करके इस तरह कोड लिखा था। मेरा लूप केवल एकमात्र महत्वपूर्ण अंतर था: (int i = 0 ;; i ++) और जब आइटम वापस वापस आया तो मैंने लूप तोड़ दिया। ध्यान दें कि इस तरह से सीजेएसओएन सरणी पर लूपिंग ओ (एन^2) है क्योंकि cJSON_GetArrayItem ओ (एन) है। – Spike0xff

3

IMHO, इस का एक उदाहरण है एक मामला जहां आपको लाइब्रेरी के encapsulation फट जाना चाहिए और सीधे इसके ऑब्जेक्ट डेटा संरचना के साथ काम करना चाहिए।

/* The cJSON structure: */ 
typedef struct cJSON { 
    struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ 
    struct cJSON *child;  /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ 

    int type;     /* The type of the item, as above. */ 

    char *valuestring;   /* The item's string, if type==cJSON_String */ 
    int valueint;    /* The item's number, if type==cJSON_Number */ 
    double valuedouble;   /* The item's number, if type==cJSON_Number */ 

    char *string;    /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ 
} cJSON; 

(।। एक नामकरण विकल्पों लेखक बना दिया, बिल्कुल से कुछ के साथ वक्रोक्ति सकता है लेकिन अच्छी नामकरण कठिन है)

कुंजी बात: cJSON.h निम्नलिखित struct के रूप में कोर वस्तु को परिभाषित करता है ध्यान दें कि JSON ऑब्जेक्ट्स और JSON Arrays दोनों में एक गैर-शून्य child फ़ील्ड है, जो उनके बच्चों की दोगुनी-लिंक्ड सूची को इंगित करता है। जेएसओएन ऑब्जेक्ट्स के बच्चों के पास गैर-शून्य string फ़ील्ड भी हैं जिनमें उस बच्चे से जुड़े क्षेत्र का नाम शामिल है।

तो, हे (एन) समय में JSON सारणी ja से अधिक सामान्य रूप से पुनरावृति, प्रत्येक तत्व के लिए एक समारोह बुला लिए, आप कुछ इस तरह लिखना:

cJSON_ForEachItem(cJSON *ja, int (*f)(cJSON *ja, int i, cJSON *jchild)) 
{ 
    cJSON *jchild; 
    int i; 
    for (jchild=ja->child, i=0; jchild; jchild=jchild->next, ++i) { 
     // do something here with the ith child... 
     if (f(ja, i, jchild)) 
      break; 
    } 
} 

वस्तुओं के बाद से और सरणी केवल में आंतरिक रूप से अलग प्रत्येक बच्चे के आइटम के लिए नामों की उपस्थिति, वह फ़ंक्शन किसी ऑब्जेक्ट के फ़ील्ड को भी पुन: सक्रिय करेगा। कॉलबैक बता सकता है क्योंकि ja->type या तो cJSON_Array या cJSON_Object होगा, और jchild->string ऑब्जेक्ट्स के लिए भी गैर-शून्य होगा।

cJSON_GetArraySize() पर कॉल करके वही पुनरावृत्ति करना और cJSON_GetArrayItem() का उपयोग ओ (एन^2) ऑर्डर होगा क्योंकि इसे एनएच आइटम का पता लगाने के लिए प्रत्येक बार लिंक्ड सूची को पार करना होगा।

तर्कसंगत रूप से, सीजेएसओएन में कुछ सामान्य ForEach फ़ंक्शंस शामिल होना चाहिए, लेकिन यह "सबसे कमजोर संभावित पार्सर" है जिसे आप अपना काम पूरा कर सकते हैं "के अनुमानित मूल लक्ष्य से दूर-दराज के एक महत्वपूर्ण मात्रा की शुरुआत का प्रतिनिधित्व कर सकते हैं। ।

void parse_array(cJSON *array) 
{ 
    cJSON *item = array ? array->child : 0; 
    while (item) 
    { 
    cJSON *name = cJSON_GetObjectItem(item, "name"); 
    cJSON *index = cJSON_GetObjectItem(item, "index"); 
    cJSON *optional = cJSON_GetObjectItem(item, "optional"); 

    item=item->next; 
    } 
} 

यह हे से बचा जाता है (एन^2) लागत कि RBerteig सही ढंग से बताते हैं:

3

आप थोड़ा तेजी से चलाना चाहते हैं, यह क्या कोड लग रहा है की तरह है।

कॉल के साथ:

parse_array(cJSON_GetObjectItem(cJSON_Parse(request_body),"items")); 
संबंधित मुद्दे