加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

rapidjson常见使用示例

发布时间:2020-12-16 19:03:57 所属栏目:百科 来源:网络整理
导读:rapidjson相比jsoncpp性能高出太多,使用接口一样的简单的。官方中文帮助文档:http://rapidjson.org/zh-cn/。 rapidjson的Move语意,请浏览http://rapidjson.org/zh-cn/md_doc_tutorial_8zh-cn.html#MoveSemantics, 示例: rapidjson::Value a(123); rapid

rapidjson相比jsoncpp性能高出太多,使用接口一样的简单的。官方中文帮助文档:http://rapidjson.org/zh-cn/。


rapidjson的Move语意,请浏览http://rapidjson.org/zh-cn/md_doc_tutorial_8zh-cn.html#MoveSemantics,
示例:
rapidjson::Value a(123);
rapidjson::Value b(456);
b = a; // a变成Null,b变成数字123,这样的做法是基于性能考虑


除了上述示例的复制语句外,AddMember()和PushBack()也采用了Move语意。


深复制Value:
Value v1("foo");
// Value v2(v1); // 不容许
Value v2(v1,a); // 制造一个克隆,v1不变


Document d;
v2.CopyFrom(d,a); // 把整个document复制至v2,d不变


rapidjson为了最大化性能,大量使用了浅拷贝,使用之前一定要了解清楚。
如果采用了浅拷贝,特别要注意局部对象的使用,以防止对象已被析构了,却还在被使用。


// 需要#include的头文件:
#include <rapidjson/document.h>
#include <rapidjson/error/en.h> // en为english的简写,定义了取出错信息的函数GetParseError_En(errcode)
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>

// 示例1:解析一个字符串
// 运行输出结果:
// count=2
// name=zhangsan
// name=wangwu
void x1()
{
    rapidjson::Document document; // 定义一个Document对象
    std::string str = "{"count":2,"names":["zhangsan","wangwu"]}";

    document.Parse(str.c_str()); // 解析,Parse()无返回值,也不会抛异常
    if (document.HasParseError()) // 通过HasParseError()来判断解析是否成功
    {
        // 可通过GetParseError()取得出错代码,
        // 注意GetParseError()返回的是一个rapidjson::ParseErrorCode类型的枚举值
        // 使用函数rapidjson::GetParseError_En()得到错误码的字符串说明,这里的En为English简写
        // 函数GetErrorOffset()返回出错发生的位置
        printf("parse error: (%d:%d)%sn",document.GetParseError(),document.GetErrorOffset(),rapidjson::GetParseError_En(document.GetParseError()));
    }
    else
    {
        // 判断某成员是否存在
        if (!document.HasMember("count") || !document.HasMember("names"))
        {
            printf("invalid format: %sn",str.c_str());
        }
        else
        {
            // 如果count不存在,则运行程序会挂,DEBUG模式下直接abort
            rapidjson::Value& count_json = document["count"];
            
            // 如果count不是整数类型,调用也会挂,DEBUG模式下直接abort
            // GetInt()返回类型为int
            // GetUint()返回类型为unsigned int
            // GetInt64()返回类型为int64_t
            // GetUint64()返回类型为uint64_t
            // GetDouble()返回类型为double
            // GetString()返回类型为char*
            // GetBool()返回类型为bool
            int count = count_json.GetInt();
            printf("count=%dn",count);
            
            // 方法GetType()返回枚举值: kNullType,kFalseType,kTrueType,kObjectType,kArrayType,kStringType,kNumberType
            // 可用IsArray()判断是否为数组,示例: { "a": [1,2,3,4] }
            // 用IsString()判断是否为字符串值
            // 用IsDouble()判断是否为double类型的值,示例: { "pi": 3.1416 }
            // 用IsInt()判断是否为int类型的值
            // 用IsUint()判断是否为unsigned int类型的值
            // 用IsInt64()判断是否为int64_t类型的值
            // 用IsUint64()判断是否为uint64_t类型的值
            // 用IsBool()判断是否为bool类型的值
            // 用IsFalse()判断值是否为false,示例: { "t": true,"f": false }
            // 用IsTrue()判断值是否为true
            // 用IsNull()判断值是否为NULL,示例: { "n": null }
            // 更多说明可浏览:
            // https://miloyip.gitbooks.io/rapidjson/content/zh-cn/doc/tutorial.zh-cn.html

            const rapidjson::Value& names_json = document["names"];
            for (rapidjson::SizeType i=0; i<names_json.Size(); ++i)
            {
                std::string name = names_json[i].GetString();
                printf("name=%sn",name.c_str());
            }
        }
    }
}

// 示例2:构造一个json并转成字符串
// 输出结果:
// {"count":2,"names":[{"name":"zhangsan"},{"name":"wangwu"}]}
void x2()
{
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);

    writer.StartObject();

    // count
    writer.Key("count");
    writer.Int(2);
    // 写4字节有符号整数: Int(int32_t x)
    // 写4字节无符号整数: Uint(uint32_t x)
    // 写8字节有符号整数: Int64(int64_t x)
    // 写8字节无符号整数: Uint64(uint64_t x)
    // 写double值: Double(double x)
    // 写bool值: Bool(bool x)

    // names
    writer.Key("names");
    writer.StartArray();

    writer.StartObject();
    writer.Key("name");
    writer.String("zhangsan");
    writer.EndObject();

    writer.StartObject();
    writer.Key("name");
    writer.String("wangwu");
    writer.EndObject();

    writer.EndArray();
    writer.EndObject();

    // 以字符串形式打印输出
    printf("%sn",buffer.GetString());
}

// 示例3:修改一个已有的json字符串
// 运行输出结果:
// {"name":"wangwu","age":22}
void x3()
{
    rapidjson::Document document;
    std::string str = "{"name":"zhangsan","age":20}";
    document.Parse(str.c_str());

    rapidjson::Value& name_json = document["name"];
    rapidjson::Value& age_json = document["age"];
    std::string new_name = "wangwu";
    int new_age = 22;

    // 注意第三个参数是document.GetAllocator(),相当于深拷贝,rapidjson会分配一块内存,然后复制new_name.c_str(),
    // 如果不指定第三个参数,则是浅拷贝,也就是rapidjson不会分配一块内存,而是直接指向new_name.c_str(),省去复制提升了性能
    // 官方说明:
    // http://rapidjson.org/zh-cn/md_doc_tutorial_8zh-cn.html#CreateString
    name_json.SetString(new_name.c_str(),new_name.size(),document.GetAllocator());
    age_json.SetInt(new_age);

    // 转成字符串输出
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    document.Accept(writer);
    printf("%sn",buffer.GetString());
}

// 示例4:读数组
// 运行输出结果:
// zhangsan wangwu 
void x4()
{
    rapidjson::Document document;
    std::string str = "{"count":2,"names":[{"name":"zhangsan"},{"name":"wangwu"}]}";

    document.Parse(str.c_str());
    if (document.HasParseError())
    {
        printf("parse error: %dn",document.GetParseError());
    }
    else
    {
        rapidjson::Value& names_json = document["names"];
        for (rapidjson::SizeType i=0; i<names_json.Size(); ++i)
        {
            if (names_json[i].HasMember("name"))
            {
                rapidjson::Value& name_json = names_json[i]["name"];
                printf("%s ",name_json.GetString());
            }
        }
        printf("n");
    }
}

// 示例5: 以Writer构造一个json,然后修改它,最后转成字符串
// 运行输出结果:
// {"count":2}
// {"count":8}
void x5()
{
    rapidjson::StringBuffer buffer1;
    rapidjson::Writer<rapidjson::StringBuffer> writer1(buffer1);
    
    writer1.StartObject();
    writer1.Key("count");
    writer1.Int(2);    
    writer1.EndObject();
    printf("%sn",buffer1.GetString());

    // 转成Document对象
    rapidjson::Document document;
    document.Parse(buffer1.GetString());

    // 修改
    rapidjson::Value& count_json = document["count"];
    count_json.SetInt(8);
    
    // 转成字符串
    rapidjson::StringBuffer buffer2;
    rapidjson::Writer<rapidjson::StringBuffer> writer2(buffer2);

    document.Accept(writer2);
    printf("%sn",buffer2.GetString());
}

// 示例6: 以Document构造一个json,然后修改它,最后转成字符串
// 运行输出结果:
// {"count":3,"names":[{"id":1,"name":"zhangsan"}]}
// {"count":9,"name":"zhangsan"}]}
void x6()
{
    rapidjson::Document document;
    std::string str = "{}"; // 这个是必须的,且不能为"",否则Parse出错
    document.Parse(str.c_str());

    // 新增成员count
    document.AddMember("count",document.GetAllocator());

    // 新增数组成员
    rapidjson::Value array(rapidjson::kArrayType);
    rapidjson::Value object(rapidjson::kObjectType); // 数组成员
    object.AddMember("id",1,document.GetAllocator()); 
    object.AddMember("name","zhangsan",document.GetAllocator()); 
    
    // 注意下面用法编译不过:
    //std::string str1 = "hello";
    //object.AddMember("name",str1.c_str(),document.GetAllocator());
    //const char* str2 = "hello";
    //object.AddMember("name",str2,document.GetAllocator());
    //
    // 下面这样可以:
    //object.AddMember("name","hello",document.GetAllocator());
    //const char str3[] = "hello";
    //object.AddMember("name",str3,document.GetAllocator());
    //    
    //std::string str4 = "#####";
    //rapidjson::Value v(str4.c_str(),document.GetAllocator());
    //obj.AddMember("x",v,document.GetAllocator());
    // 上面两行也可以写在一行:
    //obj.AddMember("x",rapidjson::Value(str4.c_str(),document.GetAllocator()).Move(),document.GetAllocator());

    // 添加到数组中
    array.PushBack(object,document.GetAllocator());
    // 添加到document中
    document.AddMember("names",array,document.GetAllocator());

    // 转成字符串输出
    rapidjson::StringBuffer buffer1;
    rapidjson::Writer<rapidjson::StringBuffer> writer1(buffer1);
    document.Accept(writer1);
    printf("%sn",buffer1.GetString());
    
    // 修改值
    rapidjson::Value& count_json = document["count"];
    count_json.SetInt(9);

    // 再次输出
    rapidjson::StringBuffer buffer2;
    rapidjson::Writer<rapidjson::StringBuffer> writer2(buffer2);
    document.Accept(writer2);
    printf("%sn",buffer2.GetString());
}

// 不转义就输出
// 示例7: 以Document构造一个json,然后修改它,最后转成字符串
// 运行输出结果:
// x7=>
// {"title":"u8D2Bu56F0u5B64u513Fu52A9u517B"}
void x7()
{
    std::string root = "{}";
    rapidjson::Document document;
    document.Parse(root.c_str());

    std::string title = "u8D2Bu56F0u5B64u513Fu52A9u517B";
    document.AddMember("title",rapidjson::Value(title.c_str(),document.GetAllocator());

    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer,rapidjson::Document::EncodingType,rapidjson::ASCII<> > writer(buffer);
    // 如果上面一句改成普通的:
    // rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    // 则输出将变成:
    // x7=>
    // 贫困孤儿助养
    
    document.Accept(writer);
    printf("x7=>n%sn",buffer.GetString());
}

// 示例8:构造空对象和数组 
// 运行输出结果:
// {"age":{},"times":{},"names":[],"urls":[],"books":[]}
// {"age":6,"books":[]}
void x8()
{
    rapidjson::Document document;
    document.Parse("{}"); // 这里换成document.SetObject()也可以

    // 下面为2种构造空对象的方法
    document.AddMember("age",rapidjson::Value(rapidjson::kObjectType).Move(),document.GetAllocator());
    document.AddMember("times",rapidjson::Value().SetObject(),document.GetAllocator());

    // 下面为2种构造空数组的方法
    document.AddMember("names",rapidjson::Value(rapidjson::kArrayType).Move(),document.GetAllocator());
    document.AddMember("urls",document.GetAllocator());
    document.AddMember("books",rapidjson::Value().SetArray(),document.GetAllocator());

    rapidjson::StringBuffer buffer1;
    rapidjson::Writer<rapidjson::StringBuffer> writer1(buffer1);
    document.Accept(writer1);
    printf("%sn",buffer1.GetString());

    rapidjson::Value& age = document["age"];
    age.SetInt(6);

    rapidjson::StringBuffer buffer2;
    rapidjson::Writer<rapidjson::StringBuffer> writer2(buffer2);
    document.Accept(writer2);
    printf("%sn",buffer2.GetString());
}

int main()
{
    x1();
    x2();
    x3();
    x4();
    x5();
    x6();
    x7();
    x8();
    return 0;
}

// 示例:不转义中文
// 运行输出结果:
//{"title":"贫困孤儿助养"}
//{"title":"u8D2Bu56F0u5B64u513Fu52A9u517B"}
//g++ -g -o b b.cpp -I/usr/local/thirdparty/rapidjson/include
#include <rapidjson/document.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>
#include <string>
#include <stdio.h>

int main()
{
    std::string str = "{"title":"u8d2bu56f0u5b64u513fu52a9u517b"}";
    rapidjson::Document document;
    document.Parse(str.c_str());
    if (document.HasParseError())
    {
        printf("parse %s failedn",str.c_str());
        exit(1);
    }

    rapidjson::StringBuffer buffer1;
    rapidjson::Writer<rapidjson::StringBuffer> writer1(buffer1);
    document.Accept(writer1);
    printf("%sn",buffer1.GetString());

    rapidjson::StringBuffer buffer2;
    rapidjson::Writer<rapidjson::StringBuffer,rapidjson::ASCII<> > writer2(buffer2);
    document.Accept(writer2);
    printf("%sn",buffer2.GetString());

    return 0;
}

// 辅助函数:任意类型都以字符串返回,
// 如果不存在,或者为数组则返回空字符串。
std::string rapidjson_string_value(rapidjson::Value& value,const std::string& name)
{
    if (!value.HasMember(name.c_str()))
        return std::string("");

    const rapidjson::Value& child = value[name.c_str()];
    if (child.IsString())
        return child.GetString();

    char str[100];
    if (child.IsInt())
    {
        snprintf(str,sizeof(str),"%d",child.GetInt());
    }
    else if (child.IsInt64())
    {
        // 为使用PRId64,需要#include <inttypes.h>,
        // 同时编译时需要定义宏__STDC_FORMAT_MACROS
        snprintf(str,"%"PRId64,child.GetInt64());
    }
    else if (child.IsUint())
    {
        snprintf(str,"%u",child.GetUint());
    }
    else if (child.IsUint64())
    {
        snprintf(str,"%"PRIu64,child.GetUint64());
    }
    else if (child.IsDouble())
    {
        snprintf(str,"%.2lf",child.GetDouble());
    }
    else if (child.IsBool())
    {
        if (child.IsTrue())
            strcpy(str,"true");
        else
            strcpy(str,"false");
    }
    else
    {
        str[0] = '';
    }

    return str;
}

// 辅助函数:
// 当为int32_t值,或字符串实际为int32_t值时,返回对应的int32_t值,其它情况返回0
int32_t rapidjson_int32_value(rapidjson::Value& value,const std::string& name)
{
    if (!value.HasMember(name.c_str()))
        return 0;

    const rapidjson::Value& child = value[name.c_str()];
    if (child.IsInt())
    {
        return child.GetInt();
    }
    else if (child.IsString())
    {
        return atoi(child.GetString());
    }

    return 0;
}

// 辅助函数:
// 当为int64_t值,或字符串实际为int64_t值时,返回对应的int64_t值,其它情况返回0
int64_t rapidjson_int64_value(rapidjson::Value& value,const std::string& name)
{
    if (!value.HasMember(name.c_str()))
        return 0;

    const rapidjson::Value& child = value[name.c_str()];
    if (child.IsInt64())
    {
        return child.GetInt64();
    }
    else if (child.IsString())
    {
        return (int64_t)atoll(child.GetString());
    }

    return 0;
}

// 辅助函数:
// 当为uin32_t值,或字符串实际为uin32_t值时,返回对应的uin32_t值,其它情况返回0
uint32_t rapidjson_uint32_value(rapidjson::Value& value,const std::string& name)
{
    if (!value.HasMember(name.c_str()))
        return 0;

    const rapidjson::Value& child = value[name.c_str()];
    if (child.IsUint())
    {
        return child.GetUint();
    }
    else if (child.IsString())
    {
        return (uint32_t)atoll(child.GetString());
    }

    return 0;
}

// 辅助函数:
// 当为uin64_t值,或字符串实际为uin64_t值时,返回对应的uin64_t值,其它情况返回0
uint64_t rapidjson_uint64_value(rapidjson::Value& value,const std::string& name)
{
    if (!value.HasMember(name.c_str()))
        return 0;

    const rapidjson::Value& child = value[name.c_str()];
    if (child.IsUint64())
    {
        return child.GetUint64();
    }
    else if (child.IsString())
    {
        return (uint64_t)atoll(child.GetString());
    }

    return 0;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读