rapidjson常见使用示例

摘要:
//A变为空;GetParseError被定义为用于获取错误信息的函数_ En(错误代码)#include<“names”:GetParseError_En()获取错误代码文档的字符串描述。GetErrorOffset():GetParseError_En(document.GetParseError()):str.c_str():

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)%s ", document.GetParseError(), document.GetErrorOffset(), rapidjson::GetParseError_En(document.GetParseError()));
    }
    else
    {
        // 判断某成员是否存在
        if (!document.HasMember("count") || !document.HasMember("names"))
        {
            printf("invalid format: %s ", 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=%d ", 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=%s ", 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("%s ", 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("%s ", 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: %d ", 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(" ");
    }
}


// 示例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("%s ", 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("%s ", buffer2.GetString());
}


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


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


    // 新增数组成员
    rapidjson::Value array(rapidjson::kArrayType);
    rapidjson::Value object(rapidjson::kObjectType); // 数组成员
    object.AddMember("id", 1, document.GetAllocator()); 
    object.AddMember("name", "zhangsan", document.GetAllocator()); 
    
    // 如果数组添加无名字的成员,定义Value时应当改成相应的类型,如:
    //rapidjson::Value value(rapidjson::kStringType);
    //rapidjson::Value value(rapidjson::kNumberType);
    //rapidjson::Value value(rapidjson::kFalseType);
    //rapidjson::Value value(rapidjson::kTrueType);
    //array.PushBack(value, document.GetAllocator());
    //效果将是这样:'array':[1,2,3,4,5]
    
    // 注意下面用法编译不过:
    //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("%s ", 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("%s ", 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()).Move(), 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=> %s ", buffer.GetString());
}


// 示例8:构造空对象和数组 
// 运行输出结果:
// {"age":{},"times":{},"names":[],"urls":[],"books":[]}
// {"age":6,"times":{},"names":[],"urls":[],"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", rapidjson::Value(rapidjson::kArrayType).Move(), document.GetAllocator());
    document.AddMember("books", rapidjson::Value().SetArray(), document.GetAllocator());


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


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


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


// 删除数组元素
// 示例运行输出:
// { "names": [ {"name":"zhangsan","age":100}, {"name":"wangwu","age":90}, {"name":"xiaozhang","age":20} ]}
// {"names":[{"name":"zhangsan","age":100},{"name":"wangwu","age":90}]}
void x9()
{
    std::string str = "{ "names": [ {"name":"zhangsan","age":100}, {"name":"wangwu","age":90}, {"name":"xiaozhang","age":20} ]}";
    
    rapidjson::Document document;
    document.Parse(str.c_str());
    
    rapidjson::Value& names_json = document["names"];
    for (rapidjson::Value::ValueIterator iter=names_json.Begin(); iter!=names_json.End();)
    {
        std::string name = (*iter)["name"].GetString();
        
        // 不要小张了
        if (name == "xiaozhang")
            iter = names_json.Erase(iter);
        else
            ++iter;
    }
    
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    document.Accept(writer);
    
    printf("%s ", str.c_str());
    printf("%s ", buffer.GetString());
}


int main()
{
    x1();
    x2();
    x3();
    x4();
    x5();
    x6();
    x7();
    x8();
    x9();
    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 failed ", str.c_str());
        exit(1);
    }


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


    rapidjson::StringBuffer buffer2;
    rapidjson::Writer<rapidjson::StringBuffer, rapidjson::Document::EncodingType, rapidjson::ASCII<> > writer2(buffer2);
    document.Accept(writer2);
    printf("%s ", 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, sizeof(str), "%"PRId64, child.GetInt64());
    }
    else if (child.IsUint())
    {
        snprintf(str, sizeof(str), "%u", child.GetUint());
    }
    else if (child.IsUint64())
    {
        snprintf(str, sizeof(str), "%"PRIu64, child.GetUint64());
    }
    else if (child.IsDouble())
    {
        snprintf(str, sizeof(str), "%.2lf", child.GetDouble());
    }
    else if (child.IsBool())
    {
        if (child.IsTrue())
            strcpy(str, "true");
        else
            strcpy(str, "false");
    }
    else
    {
        str[0] = '

免责声明:内容来源于网络,仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇JAVA中Sessionuniapp路由插件使用爬坑下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

openssl编程轻松入门(含完整示例)

 openssl编程入门(含完整示例).pdf      openssl编程轻松入门(含完整示例) 一见 1. 编写目的第一次跑起openssl示例并不太简单,本文的目的是为了让这个过程变得非常简单。在开始之前,要非常感谢周立发同学,正是通过他共享的示例,较轻松的入了门。本文档对他共享的示例中的一个小错误进行了修正,并提供了傻瓜式的“编译-生成-KE...

Java10 新特性

一、JDK10 发布   2018年3月21日, Oracle官方宣布Java10正式发布。   需要注意的是 Java 9 和 Java 10 都不是 LTS (Long-Term-Support) 版本。和过去的 Java 大版本升级不同,这两个只有半年左右的开发和维护期。而未来的 Java 11,也就是 18.9 LTS,才是 Java 8 之后第一个...

mysql explain用法和结果的含义

  转自:http://blog.chinaunix.net/uid-540802-id-3419311.html   (转载只是为了以后更方便的查看) explain显示了mysql如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。 使用方法,在select语句前加上explain就可以了: 如: expla...

多线程和异步委托基础详解

在讲多线程前。先回忆下异步委托:       /*            异步委托自我解释:即用.net委托来自动创建次线程(子线程)以处理异步方法的调用         * 当调用BeginInvoke()方法的时候,程序就会自动创建一个子线程去处理异步委托的方法。         */ //线程被定义为可执行应用程序中的基本执行单元 1 //1:S...

Effective C# 原则9:明白几个相等运算之间的关系(译)

Effective C# 原则9:明白几个相等运算之间的关系(译)Item 9: Understand the Relationships Among ReferenceEquals(), static Equals(), instance Equals(), and operator== 明白ReferenceEquals(), static Equal...

GBT 33200-2016 社会治安综合治理 综治中心建设与管理规范 GBT 31000-2015 社会治安综合治理基础数据规范

阚总发的两个国标的标准文件, 看看里面对于数据和问题的分类等。 我们出统计分析,可以按照标准出各个大类小类的各种指标数据。 结合这几天给潍坊弄的12345的报告, 整理出一个可以结合吴中现有平台数据,形成一个可以做到的分析的list。 == 数据和问题的分类 各个大类小类的各种指标数据 可以做到的分析的list。 如果按照那些人,估计是需要给他们一个表格。...