1.首先来说下遇到的一个坑,如果rappidjson中json的某一个字段对应的内容不是object对象,使用HasMember函数会报assert IsObject() failed的错误,然后程序崩溃。
举个例子:
json内容如下:
{
“action”: “result”,
“code”: “0”,
“data”: “{“cn”:{“st”:{“bg”:“820”,“ed”:“0”,“rt”:[{“ws”:[{“cw”:[{“w”:“啊”,“wp”:“n”}],“wb”:0,“we”:0},{“cw”:[{“w”:“喂”,“wp”:“n”}],“wb”:0,“we”:0},{“cw”:[{“w”:”!“,“wp”:“p”}],“wb”:0,“we”:0},{“cw”:[{“w”:“你好”,“wp”:“n”}],“wb”:0,“we”:0},{“cw”:[{“w”:”!“,“wp”:“p”}],“wb”:0,“we”:0},{“cw”:[{“w”:“我”,“wp”:“n”}],“wb”:0,“we”:0},{“cw”:[{“w”:“是”,“wp”:“n”}],“wb”:0,“we”:0},{“cw”:[{“w”:“上”,“wp”:“n”}],“wb”:0,“we”:0}]}],“type”:“1”}},“seg_id”:5}\n”,
“desc”: “success”,
“sid”: “rta0000000e@ch312c0e3f6bcc9f0900”
}
上面整个json的内容为:rapidjson::Document jdata,如果直接使用jdata.HasMember(“data”),就会报上面assert IsObject() failed的错误,然后程序崩溃。解决方法如下:
(1)观察data字段后发现,data的内容实际为字符串,因此可以做如下处理:
Document jdata;
std::string data = jresult[“data”].GetString();
if (jdata.Parse(data.c_str()).HasParseError())
{
//todo
//做一些错误处理,然后根据实际业务判断是否退出
}
这个例子中,jdata就成为一个对象,可以做jdata.HasMember(“cn”)这样的操作,判断json对象中是否有某个字段,如果jdata对象中还有某些字段的值对应的内容是字符串并且内容实际上是一个对象,可以继续做上面类似的逻辑处理。
2.rapidjson中主要的几种数据类型,可以参考rapidjson/document.h头文件
//! Type of JSON value
enum Type {
kNullType = 0, //!< null
kFalseType = 1, //!< false
kTrueType = 2, //!< true
kObjectType = 3, //!< object
kArrayType = 4, //!< array
kStringType = 5, //!< string
kNumberType = 6 //!< number
};
对应的类型判断函数主要有如下几种:
//!@name Type
//@{
Type GetType() const { return static_cast<Type>(data_.f.flags & kTypeMask); }
bool IsNull() const { return data_.f.flags == kNullFlag; }
bool IsFalse() const { return data_.f.flags == kFalseFlag; }
bool IsTrue() const { return data_.f.flags == kTrueFlag; }
bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; }
bool IsObject() const { return data_.f.flags == kObjectFlag; }
bool IsArray() const { return data_.f.flags == kArrayFlag; }
bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; }
bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; }
bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; }
bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }