RapidJSON是腾讯开源的一个高效的C++ JSON解析器及生成器,它是只有头文件的C++库。RapidJSON是跨平台的,支持Windows, Linux, Mac OS X及iOS, Android。它的源码在【】https://github.com/Tencent/rapidjson/,稳定版本为2016年发布的1.1.0版本。 官网地址
RapidJSON特点
每个JSON值都储存为Value类,而Document类则表示整个DOM,它存储了一个DOM 树的根Value。RapidJSON的所有公开类型及函数都在rapidjson命名空间中。
以上内容摘自:官网,关于RapidJSON的更详细介绍可以参考此网页。
以下是测试代码(test_rapidjson.cpp):
#include "funset.hpp"
#include "rapidjson/document.h"
//#include "rapidjson/writer.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
#include <iostream>
#include <fstream>
#include <string>
#include "common.hpp"
int test_rapidjson_parse()
{
#ifdef _MSC_VER
const char* file_name = "E:/GitCode/Messy_Test/testdata/json.data";
#else
const char* file_name = "testdata/json.data";
#endif
std::ifstream in(file_name);
if (!in.is_open()) {
fprintf(stderr, "fail to read json file: %s\n", file_name);
return -1;
}
std::string json_content((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
in.close();
rapidjson::Document dom;
if (!dom.Parse(json_content.c_str()).HasParseError()) {
if (dom.HasMember("name") && dom["name"].IsString()) {
fprintf(stdout, "name: %s\n", dom["name"].GetString());
}
if (dom.HasMember("address") && dom["address"].IsString()) {
fprintf(stdout, "address: %s\n", utf8_to_gbk(dom["address"].GetString()));
}
if (dom.HasMember("age") && dom["age"].IsInt()) {
fprintf(stdout, "age: %d\n", dom["age"].GetInt());
}
const char* tmp = "xxx";
if (!dom.HasMember(tmp)) {
fprintf(stdout, "Warning: it has no member: %s\n", tmp);
}
if (dom.HasMember("value1") && dom["value1"].IsArray()) {
const rapidjson::Value& arr = dom["value1"];
for (int i = 0; i < arr.Size(); ++i) {
const rapidjson::Value& tmp = arr[i];
fprintf(stdout, "value1:\ni = %d:", i);
for (int j = 0; j < tmp.Size(); ++j) {
if (tmp[j].IsInt())
fprintf(stdout, "%d, ", tmp[j].GetInt());
if (tmp[j].IsFloat())
fprintf(stdout, "%.1f, ", tmp[j].GetFloat());
}
fprintf(stdout, "\n");
}
}
if (dom.HasMember("value2") && dom["value2"].IsArray()) {
const rapidjson::Value& arr = dom["value2"];
fprintf(stdout, "value2: ");
for (int i = 0; i < arr.Size(); ++i) {
fprintf(stdout, "%.2f, ", arr[i].GetFloat());
}
fprintf(stdout, "\n");
}
if (dom.HasMember("bei_jing") && dom["bei_jing"].IsObject()) {
const rapidjson::Value& obj = dom["bei_jing"];
if (obj.HasMember("address") && obj["address"].IsString()) {
fprintf(stdout, "address: %s\n", utf8_to_gbk(obj["address"].GetString()));
}
if (obj.HasMember("car") && obj["car"].IsBool()) {
fprintf(stdout, "car: %d\n", obj["car"].GetBool());
}
if (obj.HasMember("cat") && obj["cat"].IsBool()) {
fprintf(stdout, "cat: %d\n", obj["cat"].GetBool());
}
}
if (dom.HasMember("shan_dong") && dom["shan_dong"].IsObject()) {
const rapidjson::Value& obj = dom["shan_dong"];
if (obj.HasMember("address") && obj["address"].IsString()) {
fprintf(stdout, "address: %s\n", utf8_to_gbk(obj["address"].GetString()));
}
if (obj.HasMember("value1") && obj["value1"].IsArray()) {
const rapidjson::Value& arr = obj["value1"];
if (arr[0].HasMember("ji_nan") && arr[0]["ji_nan"].IsString()) {
fprintf(stdout, "ji_nan: %s\n", utf8_to_gbk(arr[0]["ji_nan"].GetString()));
}
if (arr[0].HasMember("tai_an") && arr[0]["tai_an"].IsString()) {
fprintf(stdout, "tai_an: %s\n", utf8_to_gbk(arr[0]["tai_an"].GetString()));
}
}
}
} else {
fprintf(stderr, "fail to parse json file: %s\n", file_name);
return -1;
}
// iter json
for (rapidjson::Value::ConstMemberIterator iter = dom.MemberBegin(); iter != dom.MemberEnd(); ++iter) {
fprintf(stdout, "iter json name: %s, type: %d\n", iter->name.GetString(), iter->value.GetType());
}
return 0;
}
int test_rapidjson_write()
{
rapidjson::StringBuffer buf;
//rapidjson::Writer<rapidjson::StringBuffer> writer(buf);
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf); // it can word wrap
writer.StartObject();
writer.Key("name"); writer.String("spring");
writer.Key("address"); writer.String("北京");
writer.Key("age"); writer.Int(30);
writer.Key("value1");
writer.StartArray();
writer.StartArray();
writer.StartObject();
writer.Key("name"); writer.String("spring");
writer.Key("address"); writer.String("北京");
writer.Key("age"); writer.Int(30);
writer.Key("value1");
writer.StartArray();
writer.StartArray();
writer.Double(23); writer.Double(43); writer.Double(-2.3); writer.Double(6.7);
writer.Double(90);
writer.EndArray();
writer.StartArray();
writer.Int(-9); writer.Int(-19); writer.Int(10); writer.Int(2);
writer.EndArray();
writer.StartArray();
writer.Int(-5); writer.Int(-55);
writer.EndArray();
writer.EndArray();
writer.Key("value2");
writer.StartArray();
writer.Double(13.3); writer.Double(1.9); writer.Double(2.10);
writer.EndArray();
writer.Key("bei_jing");
writer.StartObject();
writer.Key("address"); writer.String("海淀");
writer.Key("car"); writer.Bool(false);
writer.Key("cat"); writer.Bool(true);
writer.EndObject();
writer.Key("shan_dong");
writer.StartObject();
writer.Key("address"); writer.String("济南");
writer.Key("value1");
writer.StartArray();
writer.Key("ji_nan"); writer.String("趵突泉");
writer.Key("tai_an"); writer.String("泰山");
writer.EndArray();
writer.EndObject();
writer.EndObject();
const char* json_content = buf.GetString();
fprintf(stdout, "json content: %s\n", json_content);
#ifdef _MSC_VER
const char* file_name = "E:/GitCode/Messy_Test/testdata/out.json";
#else
const char* file_name = "testdata/out.json";
#endif
std::ofstream outfile;
outfile.open(file_name);
if (!outfile.is_open()) {
fprintf(stderr, "fail to open file to write: %s\n", file_name);
return -1;
}
outfile << json_content << std::endl;
outfile.close();
return 0;
}
json.data内容如下:
{
"name": "spring",
"address": "北京",
"age": 30,
"value1": [[23, 43, -2.3, 6.7, 90],
[-9, -19, 10, 2],
[-5, -55]],
"value2": [13.3, 1.9, 2.10],
"bei_jing": {
"address": "海淀",
"car": false,
"cat": true
},
"shan_dong": {
"address": "济南",
"value1": [{"ji_nan": "趵突泉"}, {"tai_an": "泰山"}]
}
}
test_rapidjson_parse 的执行结果如下:与实际结果一致
test_rapidjson_write的执行结果如下:与预期一致,将 rapidjson::Writer<rapidjson::StringBuffer> writer(buf) 调整为 rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf) ;可使结果自动换行
#include <iostream>
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
using namespace std;
using namespace rapidjson;
int main(int argv ,char *argc[])
{
//1.把JSON解析至DOM
const char * strJson = "{\"key1\":\"value1\",\"key2\":\"value2\",\"key3\":100}";
Document doc;
doc.Parse(strJson);
cout<< strJson << endl;
//2.利用DOM作出修改
Value& v1 = doc["key2"];
v1="value_modify";
//v1.SetString("value_modify");
Value& v2 = doc["key3"];
v2.SetInt(v2.GetInt()+1);
//SetString()
//SetBool()
//SetUint()
//SetInt64()
//SetUInt64()
//SetDouble()
//SetFloat()
//SetArray()
//SetObject()
//SetNull()
//3.将DOM stringfy 为json
StringBuffer buffer;
Writer<StringBuffer> writer(buffer);
doc.Accept(writer);
cout<< buffer.GetString() << endl;
return 0;
}
解析结果:
{"key1":"value1","key2":"value2","key3":100}
{"key1":"value1","key2":"value_modify","key3":101}
文件对象模型,在RapidJson中广泛的使用。
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
using namespace std;
using namespace rapidjson;
int main(int argv ,char *argc[])
{
// 1.准备数据
string name = "MenAngel";
string gender = "boy";
int age = 23;
vector<string> hobbys = {"语文","数学","英语"};
map<string,double> score ={{"语文",80},{"数学",90},{"英语",100}};
// 2.初始化DOM
StringBuffer strBuffer;
Writer<StringBuffer> writer(strBuffer);
//2.1 根DOM开始
writer.StartObject();
writer.Key("name");
writer.String(name.c_str());
writer.Key("gender");
writer.String(gender.c_str()); writer.Key("age"); writer.Int(age);
writer.Key("hobby");
writer.StartArray();
for(auto &item : hobbys)
{
writer.String(item.c_str());
}
writer.EndArray();
writer.Key("scores");
writer.StartObject();
for(auto &item : scores)
{
writer.Key((item.first).c_str());
writer.Double(item.second);
}
writer.EndObject();
//2.2 根DOM结束
writer.EndObject();
//3.将上述DOM组织的json数据写入json.txt文件
string outFileName = "json.txt";
ofstream outfile(outFileName,std::ios::trunc);
outfile<<strBuffer.GetString()<<endl;
outfile.flush();
outfile.close();
return 0;
}
结果打印:
{"name":"MenAngel","gender":"boy","age":23,"hobbys":["语文","数学","英语"],
"scores":{"数学":90.0,"英语":100.0,"语文":80.0}}
其他就不copy了,有兴趣的可以自己去看看