Cocos2d-x 3.0的发布,使得我们的数据可以解析后保存在数据或字典中,具体是怎么操作的呢?本篇教程将教你怎么把数据根据数据格式保存到数组或字典中。
以前在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;
}
创建个类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(thob)) {
cout<<"{";
CCDictionary *temp=(CCDictionary *)thob;
CCDictElement *ele;
CCDICT_FOREACH(temp, ele){
const char *key=ele->getStrKey();
CCObject *ob=ele->getObject();
cout<
for (int i=0; i
cout<
}
cout<
for (int i=0; i
cout<<"}";
if (dot) {
cout<<",";
}
}else if (dynamic_cast(thob)){
cout<<"(";
CCArray *temp=(CCArray *)thob;
CCObject *ob;
CCARRAY_FOREACH(temp, ob){
if (dynamic_cast(ob)) {
if (ob!=temp->lastObject()) {
this->ccout(ob,donotset+1,true);
}else{
this->ccout(ob,donotset+1);
}
}else
if (dynamic_cast(ob)) {
this->ccout(ob,donotset+1);
}else if (dynamic_cast(ob)) {
cout<<((CCString*)ob)->getCString();
if (ob!=temp->lastObject()) {
cout<<",";
}
}else{
cout<<"undefined class cout";
}
}
cout<<")";
}
}
输出结果:
({
中国食谱=(上海醉蟹,北京锅烧鸡,川式凉拌豇豆,清真酱牛肉);
国外食谱=(泰式柠檬肉片,鸡柳汉堡,蒸桂鱼卷 );
更多={
中式=(南,北,{
地方=(小吃,大餐);
},更多选择);
};
},{
菜谱分类=(上海菜,贵州菜,潮汕菜,云南菜,东北菜,安徽菜,广东菜,浙江菜,湖南菜);
},其它)
¥98.00
¥98.00
¥698.00
¥108.00