rapidjson文档嵌套属性查询时IsObject()返回结果不一致问题
问题根因
你代码的核心错误是误用了C引用的特性:
你声明的rapidjson::Value& v是绑定到原Document节点的左值引用,C中引用一旦绑定后无法修改指向,你后续执行v = v[p];操作时,并不是让v指向更深层级的子节点,而是直接把原Document中v当前绑定的节点内容,覆盖替换为了子节点v[p]的内容,直接破坏了原JSON的结构。
比如第一次查询vegetables::celery时,你首先让v绑定到了原文档的vegetables对象节点,执行v = v["celery"]后,原文档的vegetables节点直接被替换成了值为10000的整数类型节点,所以第二次查询时vegetables已经不是对象类型,IsObject()自然返回false,和你观察到的现象完全一致。
修复方法
把遍历用的变量从引用改成指针即可,指针可以修改指向,不会修改原文档内容,仅需要修改getInt函数中的遍历部分代码:
// 原来的引用声明改成指针 rapidjson::Value* v = &jsonDoc[p]; while (p = strtok(0, ":")) { printf("Looking for property `%s`\n", p); if (v->IsObject()) { puts(" - v is an object so I can look"); } else { printf(" - ERROR: v is NOT an object, I can't search for %s, property %s not found\n", p, propertyName); free(str); return 0; } if (!v->HasMember(p)) { printf(" - Error while digging: %s not found, property %s\n", p, propertyName); free(str); return 0; } else printf(" - found property '%s'\n", p); // 修改指针指向子节点,不会修改原文档 v = &(*v)[p]; } int val = v->GetInt();
修改后原JSON文档不会被意外修改,多次查询同一属性都会返回正确结果。
内容的提问来源于stack exchange,提问作者bobobobo
相关产品推荐
相关产品推荐

