【转】rapidjson 学习笔记

官方文档

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;
    };

Value其实很简单,就只有两个数据成员:Data data_和 unsigned flags_
其中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"]
,
,]

son文件中“]”包裹的是数组,"{}"包裹的是对象,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*;这里如果写成auto t = doc*则编译失败!!!因为Value的拷贝构造函数为private的!!!

    auto& t = doc;
    
    for (int i = 0; i < t.Size(); i++)
    {
        auto& ele = t*;
        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");
    }
    *

t其实还是一个数组(其实就是第一行"id", “quest”]),获取它里面的元素也用下标运算符。ele为数组t中的元素。此for循环可以打印出json文件中第一行的内容。

除了用下标实现循环遍历,rapidjson还提供了迭代器!迭代器有针对object和针对array两种!针对array的为onBegin何onEnd。此外,rapidjson还提供了一些易于操作的其他接口……可查看源码,一一了解

原文地址http://blog.csdn.net/u012085988/article/details/19833347*

学习了,value和Document的关系比较特殊,需要好好理解下:2: