以前在cocos2d-x项目中用到json解析,集成了libjson库后发现网上提供的解析方法大多是在解析过程中取得值,并没有将解析结果有效的保存起来,于是摸索一番,把解析结果根据数据格式存到数组或字典当中。

  不敢独享,代码奉上:

using namespace std;
void JsonUtil:: parseArrJSON(JSONNODE *n,CCObject **obj)
{
    if (n == NULL)
    {
        CCLOG("Invalid JSON Node\n");
        return;
    }
    bool isAry=false;
    // Parser
    JSONNODE_ITERATOR it = json_begin(n);
    char *key=json_name(*it);
    if (strcmp(key, "")==0) {
        //是数组
        *obj=CCArray::create();
        isAry=true;
    }else{
        //是字典
        *obj=CCDictionary::create();
        isAry=false;
    }
    while (it != json_end(n)) {
        if (*it == NULL) {
            CCLOG("Invalid JSON Node\n");
            return;
        }else if(json_type(*it)==JSON_NULL){
            CCString *char_str=CCString::ccs("");
            if (isAry) {
                ((CCArray *)*obj)->addObject(char_str);
            }else{
                string key=json_name(*it);
                CC_ASSERT(!key.empty());
                ((CCDictionary *)*obj)->setObject(char_str, key);
            }
        }else if (json_type(*it) == JSON_ARRAY || json_type(*it) == JSON_NODE) {
            CCObject *tempobj=NULL;
            parseArrJSON(*it,&tempobj);
            if (isAry) {
                ((CCArray *)*obj)->addObject(tempobj);
            }else{
                string key=json_name(*it);
                CC_ASSERT(!key.empty());
                ((CCDictionary *)*obj)->setObject(tempobj, key);
            }
        }
        else if(json_type(*it)==JSON_STRING){
            json_char *value = json_as_string(*it);   
            CCString *char_str=CCString::create(value);
            if (isAry) {
                ((CCArray *)*obj)->addObject(char_str);
            }else{
                string key=json_name(*it);
                CC_ASSERT(!key.empty());
                ((CCDictionary *)*obj)->setObject(char_str, key);
            }   
            json_free(value);
        }else if(json_type(*it)==JSON_NUMBER){
            //            json_int_t value = json_as_int(*it);
            json_number value = json_as_float(*it);
            CCString *char_str=CCString::createWithFormat("%.2f",value);
            if (isAry) {
                ((CCArray *)*obj)->addObject(char_str);
            }else{
                string key=json_name(*it);
                CC_ASSERT(!key.empty());
                ((CCDictionary *)*obj)->setObject(char_str, key);
            }
        }
        ++it;
    }
}
CCObject * JsonUtil:: jsonValue(const char *_char){
    JSONNODE *an = json_parse(_char);
    CCObject *obj=NULL;
    JsonUtil::parseArrJSON(an,&obj);
    json_delete(an);
    return obj;
}
View Code

  创建个类JsonUtil,包含两个静态方法,使用的时候调用JsonUtil::jsonValue(const char *_char),解析的结果会保存在字典或者数组中,例子:

const char *betem="[{\"中国食谱\":[\"上海醉蟹\",\"北京锅烧鸡\",\"川式凉拌豇豆\",\"清真酱牛肉\"],\"国外食谱\":[\"泰式柠檬肉片\",\"鸡柳汉堡\",\"蒸桂鱼卷 \"],\"更多\":{\"中式\":[\"南\",\"北\",{\"地方\":[\"小吃\",\"大餐\"]},\"更多选择\"]}},{\"菜谱分类\":[\"上海菜\",\"贵州菜\",\"潮汕菜\",\"云南菜\",\"东北菜\",\"安徽菜\",\"广东菜\",\"浙江菜\",\"湖南菜\"]},\"其它\"]";
CCArray
*ary= (CCArray *) JsonUtil::jsonValue(betem);
ccout(ary);

  这里的ccout是自定义的用来打印数组和字典的方法。cocos2d-x的CCLog跟NSLog相比起来真是差远了,哪怕把时间打印出来也好啊。

  附上ccout代码,可以用来打印保存在CCArray或CCDictionary中的json数据,勉强做成类似NSLog输出的样子:

  

void ccout(CCObject *thob,int donotset=0,bool dot=false);

void AppDelegate::ccout(CCObject *thob,int donotset,bool dot){
    if (dynamic_cast<CCDictionary *>(thob)) {
        cout<<"{";
        CCDictionary *temp=(CCDictionary *)thob;
        CCDictElement *ele;
        CCDICT_FOREACH(temp, ele){
            const char *key=ele->getStrKey();
            CCObject *ob=ele->getObject();
            cout<<endl;
            for (int i=0; i<donotset+1; i++)cout<<"\t";
            cout<<key<<"=";
            this->ccout(ob,donotset+2);
            cout<<";";
        }
        cout<<std::endl;
        for (int i=0; i<donotset; i++)cout<<"\t";
        cout<<"}";
        if (dot) {
            cout<<",";
        }
    }else if (dynamic_cast<CCArray *>(thob)){
        cout<<"(";
        CCArray *temp=(CCArray *)thob;
        CCObject *ob;
        CCARRAY_FOREACH(temp, ob){
            if (dynamic_cast<CCDictionary *>(ob)) {
                if (ob!=temp->lastObject()) {
                    this->ccout(ob,donotset+1,true);
                }else{
                    this->ccout(ob,donotset+1);
                }
            }else
                if (dynamic_cast<CCArray *>(ob)) {
                    this->ccout(ob,donotset+1);
                }else if (dynamic_cast<CCString *>(ob)) {
                    cout<<((CCString*)ob)->getCString();
                    if (ob!=temp->lastObject()) {
                        cout<<",";
                    }
                }else{
                    cout<<"undefined class cout";
                }
            
        }
        cout<<")";
    }
    
}
View Code

  输出结果:

({
        中国食谱=(上海醉蟹,北京锅烧鸡,川式凉拌豇豆,清真酱牛肉);
        国外食谱=(泰式柠檬肉片,鸡柳汉堡,蒸桂鱼卷 );
        更多={
                中式=(南,北,{
                            地方=(小吃,大餐);
                        },更多选择);
            };
    },{
        菜谱分类=(上海菜,贵州菜,潮汕菜,云南菜,东北菜,安徽菜,广东菜,浙江菜,湖南菜);
    },其它)

 

 

posted on 2013-09-17 23:30  PowerAuras  阅读(1934)  评论(1编辑  收藏  举报