https://github.com/Tencent/rapidjson官方使用手册:RapidJSON: 首页(中文版)
RapidJSON特点:
(1)RapidJSON小而全:它同时支持SAX和DOM风格的API,SAX解析器只有约500行代码。
(2) RapidJSON快:它的性能可与strlen()相比,可支持SSE2/SSE4.2加速,使用模版及内联函数去降低函数调用开销。
(3)RapidJSON独立:它不依赖于BOOST等外部库,它甚至不依赖于STL。
(4)RapidJSON对内存友好:在大部分32/64位机器上,每个JSON值只占16字节(除字符串外),它预设使用一个快速的内存分配器,令分析器可以紧凑地分配内存。
(5)RapidJSON对Unicode友好:它支持UTF-8、UTF-16、UTF-32(大端序/小端序),并内部支持这些编码的检测、校验及转码。例如,RapidJSON可以在分析一个UTF-8文件至DOM (Document Object Model, 文件对象模型)时,把当中的JSON字符串转码至UTF-16。它也支持代理对(surrogate pair)及"\u0000"(空字符)。
每个JSON值都储存为Value类,而Document类则表示整个DOM,它存储了一个DOM 树的根Value。RapidJSON的所有公开类型及函数都在rapidjson命名空间中。
在项目中只需要将 include/rapidjson 目录复制至系统或项目的 include 目录中。
- #include "funset.hpp"
- #include "rapidjson/document.h"
- // #include "rapidjson/writer.h"
- #include "rapidjson/prettywriter.h"
- #include "rapidjson/stringbuffer.h"
- #include
- #include
- #include
- #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
writer(buf); - rapidjson::PrettyWriter
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.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文件内容如下所示:
- {
- "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": "泰山"
- }
- ]
- }
- }