Cpp中使用RapidJSON

简介

官方参考文档:http://rapidjson.org/zh-cn/index.html

RapidJSON是腾讯开源的一个高效的C++ JSON解析器及生成器,它是只有头文件的C++库。RapidJSON是跨平台的,支持Windows, Linux, Mac OS X及iOS, Android。它的源码在https://github.com/Tencent/rapidjson/

解析JSON

简单例子

#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include <iostream>

using namespace rapidjson;

int main() {
    // 1. 把 JSON 解析至 DOM。
    const char* json = "{\"project\":\"rapidjson工程\",\"stars\":10}";
    Document d;
    d.Parse(json);

    // 2. 利用 DOM 作出修改。
    Value& s = d["stars"];
    s.SetInt(s.GetInt() + 1);

    // 3. 把 DOM 转换(stringify)成 JSON。
    StringBuffer buffer;
    Writer<StringBuffer> writer(buffer);
    d.Accept(writer);

    std::string sJson = buffer.GetString();
    std::cout << sJson.c_str() << std::endl;
    return 0;
}
View Code

 

复杂点的例子,基于Dom

#include <iostream>
#include <string>
#include "rapidjson/document.h"

/*
{
  "country": "中国",
  "province": [
    {
      "name": "黑龙江",
      "cities": ["哈尔滨","大庆"]
    },
    {
      "name": "广东",
      "cities": ["广州","深圳","珠海"]
    },
    {
      "name": "台湾",
      "cities": ["台北","高雄"]
    },
    {
      "name": "新疆",
      "cities": ["乌鲁木齐"]
    }
  ]
}
*/
int _tmain(int argc, _TCHAR* argv[])
{
    const char* str = "{\"country\":\"中国\",\"province\":[{\"name\":\"黑龙江\",\"cities\":[\"哈尔滨\",\"大庆\"]},{\"name\":\"广东\",\"cities\":[\"广州\",\"深圳\",\"珠海\"]},{\"name\":\"台湾\",\"cities\":[\"台北\",\"高雄\"]},{\"name\":\"新疆\",\"cities\":[\"乌鲁木齐\"]}]}";
    rapidjson::Document document;
    document.Parse(str);
    assert(document.IsObject());
    std::string s = document["country"].GetString();
    
    const rapidjson::Value& a = document["province"];
    assert(a.IsArray());
    for (rapidjson::SizeType i = 0; i < a.Size(); i++) // 使用 SizeType 而不是 size_t
    {
        const rapidjson::Value& b = a[i];
        assert(b.IsObject());
        std::string provinceName = b["name"].GetString();
        std::cout << provinceName << ": ";
        const rapidjson::Value& c = b["cities"];
        assert(c.IsArray());
        for (rapidjson::SizeType i = 0; i < c.Size(); i++)
        {
            std::string cityName = c[i].GetString();
            std::cout << cityName << " ";
        }
        std::cout << "\n";
    }
    return 0;
}
View Code

基于SAX的解析例子

#include "rapidjson/reader.h"
#include <iostream>
#include <sstream>

using namespace rapidjson;
using namespace std;

// If you can require C++11, you could use std::to_string here
template <typename T> std::string stringify(T x) {
    std::stringstream ss;
    ss << x;
    return ss.str();
}

struct MyHandler {
    std::string type;
    std::string data;

    MyHandler() : type(), data() {}

    bool Null() { type = "Null"; data.clear(); return true; }
    bool Bool(bool b) { type = "Bool:"; data = b ? "true" : "false"; return true; }
    bool Int(int i) { type = "Int:"; data = stringify(i); return true; }
    bool Uint(unsigned u) { type = "Uint:"; data = stringify(u); return true; }
    bool Int64(int64_t i) { type = "Int64:"; data = stringify(i); return true; }
    bool Uint64(uint64_t u) { type = "Uint64:"; data = stringify(u); return true; }
    bool Double(double d) { type = "Double:"; data = stringify(d); return true; }
    bool RawNumber(const char* str, SizeType length, bool) { type = "Number:"; data = std::string(str, length); return true; }
    bool String(const char* str, SizeType length, bool) { type = "String:"; data = std::string(str, length); return true; }
    bool StartObject() { type = "StartObject"; data.clear(); return true; }
    bool Key(const char* str, SizeType length, bool) { type = "Key:"; data = std::string(str, length); return true; }
    bool EndObject(SizeType memberCount) { type = "EndObject:"; data = stringify(memberCount); return true; }
    bool StartArray() { type = "StartArray"; data.clear(); return true; }
    bool EndArray(SizeType elementCount) { type = "EndArray:"; data = stringify(elementCount); return true; }
private:
    MyHandler(const MyHandler& noCopyConstruction);
    MyHandler& operator=(const MyHandler& noAssignment);
};

// 从Json中根据key返回value,(只是简单的key-value,value不支持Object/Array)
std::string GetValueByKeyFromJson(const char* json, const std::string& key)
{
    std::string sRet;
    MyHandler handler;
    rapidjson::Reader reader;
    rapidjson::StringStream ss(json);
    reader.IterativeParseInit();
    while (!reader.IterativeParseComplete())
    {
        reader.IterativeParseNext<kParseDefaultFlags>(ss, handler);
        if ("Key:" == handler.type)
        {
            if (key == handler.data)
            {
                reader.IterativeParseNext<kParseDefaultFlags>(ss, handler);
                sRet = handler.data;
                break;
            }
        }
    }
    return sRet;
}

int main() {
    const char json[] = " { \"你好\" : \"中国\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1415926, \"a\":[1, 2, 3, 4] } ";

    std::string s = GetValueByKeyFromJson(json, "你好");//"中国"
    s = GetValueByKeyFromJson(json, "pi");//"3.14159" --> 注意不是 3.1415926
    s = GetValueByKeyFromJson(json, "n");//""
    s = GetValueByKeyFromJson(json, "a");//""
    s = GetValueByKeyFromJson(json, "t");//"true"
    s = GetValueByKeyFromJson(json, "i");//"123"
    return 0;
}
View Code

 

生成Json

////////////// 生成JSON //////////////
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include <iostream>

int _tmain(int argc, _TCHAR* argv[])
{
    rapidjson::StringBuffer buf;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buf);
    //rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf); // it can word wrap

    writer.StartObject();               // Between StartObject()/EndObject(),
/*    writer.Key("hello");                // output a key,
    writer.String("world");             // follow by a value.
    writer.Key("t");
    writer.Bool(true);
    writer.Key("f");
    writer.Bool(false);
    writer.Key("n");
    writer.Null();
    writer.Key("i");
    writer.Uint(123);
    writer.Key("pi");
    writer.Double(3.1416);
    writer.Key("a");
    writer.StartArray();                // Between StartArray()/EndArray(),
    for (unsigned i = 0; i < 4; i++)
        writer.Uint(i);                 // all values are elements of the array.
    writer.EndArray();
    writer.EndObject();
    // {"hello":"world","t":true,"f":false,"n":null,"i":123,"pi":3.1416,"a":[0,1,2,3]}
    */
    
    writer.Key("country"); writer.String("中国");
    writer.Key("province");
    writer.StartArray();
    writer.StartObject();
    writer.Key("name"); writer.String("黑龙江");
    writer.Key("cities"); writer.StartArray(); writer.String("哈尔滨"); writer.String("大庆"); writer.EndArray();
    writer.EndObject();
    writer.StartObject();
    writer.Key("name"); writer.String("广东");
    writer.Key("cities"); writer.StartArray(); writer.String("广州"); writer.String("深圳"); writer.String("珠海"); writer.EndArray();
    writer.EndObject();
    writer.EndArray();

    writer.EndObject();

    const char* s = buf.GetString();//"{"country":"中国","province":[{"name":"黑龙江","cities":["哈尔滨","大庆"]},{"name":"广东","cities":["广州","深圳","珠海"]}]}"
    std::cout << s << "\n";
    return 0;
}
View Code

 

posted @ 2020-11-14 15:56  htj10  阅读(199)  评论(0编辑  收藏  举报
TOP