官方文档
https://code.google.com/p/rapidjson/wiki/UserGuide
rapidjson是一个快速解析json文件的C++库。cocostudio就使用了该库!!!
对于使用者来说,我们只需要知道两个类:
value和Document。其中Document派生自Value。(这里都是模板特化后的名字,原名字为GenericValue<...>和GenericDocument<...>
value中定义了Number, Object,String,Array等struct。然后再用一个Union将这些struct放在一起!
union Data { String s; Number n; Object o; Array a; };
其中flag标识该value的具体类型,
enum { kBoolFlag = 0x100, kNumberFlag = 0x200, kIntFlag = 0x400, kUintFlag = 0x800, kInt64Flag = 0x1000, kUint64Flag = 0x2000, kDoubleFlag = 0x4000, kStringFlag = 0x100000, kCopyFlag = 0x200000, // Initial flags of different types. kNullFlag = kNullType, kTrueFlag = kTrueType | kBoolFlag, kFalseFlag = kFalseType | kBoolFlag, kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag, kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag, kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag, kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag, kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag, kConstStringFlag = kStringType | kStringFlag, kCopyStringFlag = kStringType | kStringFlag | kCopyFlag, kObjectFlag = kObjectType, kArrayFlag = kArrayType, kTypeMask = 0xFF // bitwise-and with mask of 0xFF can be optimized by compiler };若flag为kNumberFlag ,则data中的number中的数据有效。若flag为 kStringFlag 则data中的string有效。同理, kObjectFlag 和 kArrayFlag 对应data中的object和array。
下面试试如何使用rapidjson。
json中文件内容为:
[["id","quest"] ,[1,"quest001"] ,[2,"quest002"]]json文件中“[]”包裹的是数组,"{}"包裹的是对象,k-v用“key”:“value”的形式表示。
下面开始解析这个文件
Document doc; std::string data = FileUtils::getInstance()->getStringFromFile("haha.json"); doc.Parse<kParseDefaultFlags>(data.c_str());只需这三部,json就被解析到了doc中,此时,doc中的flag标识为kArrayFlag。接下来就是从doc中获取值了。如何从数组中获取值呢?rapidjson重载了下标运算符"[]"。在下标中传入索引,就能获取到对应的的Value了。但这里有一点要特别注意!!!就是在接收返回值时,一定要用引用!如auto& t = doc[i];这里如果写成auto t = doc[i]则编译失败!!!因为Value的拷贝构造函数为private的!!!
auto& t = doc[1]; for (int i = 0; i < t.Size(); i++) { auto& ele = t[i]; if (ele.IsInt()) CCLOG("%d", ele.GetInt()); else if (ele.IsString()) CCLOG(ele.GetString()); else if (ele.IsBool()) if (ele.GetBool()) CCLOG("true"); else CCLOG("false"); else CCLOG("flag error"); }
除了用下标实现循环遍历,rapidjson还提供了迭代器!迭代器有针对object和针对array两种!针对array的为onBegin何onEnd。此外,rapidjson还提供了一些易于操作的其他接口……可查看源码,一一了解