C++解析Json之 RapidJson库

简介

RapidJSON 是一个 C++ 的 JSON 解析器及生成器。它的灵感来自 RapidXml

  • RapidJSON 小而全。它同时支持 SAX 和 DOM 风格的 API。SAX 解析器只有约 500 行代码。
  • RapidJSON 快。它的性能可与 strlen() 相比。可支持 SSE2/SSE4.2 加速。
  • RapidJSON 独立。它不依赖于 BOOST 等外部库。它甚至不依赖于 STL。
  • RapidJSON 对内存友好。在大部分 32/64 位机器上,每个 JSON 值只占 16 字节(除字符串外)。它预设使用一个快速的内存分配器,令分析器可以紧凑地分配内存。
  • RapidJSON 对 Unicode 友好。它支持 UTF-8、UTF-16、UTF-32 (大端序/小端序),并内部支持这些编码的检测、校验及转码。例如,RapidJSON 可以在分析一个 UTF-8 文件至 DOM 时,把当中的 JSON 字符串转码至 UTF-16。它也支持代理对(surrogate pair)及 "\u0000"(空字符)

使用方法:RapidJSON: 首页icon-default.png?t=M4ADhttp://rapidjson.org/zh-cn/index.html

首先加载头文件

#include"rapidjson/reader.h"
#include"rapidjson/schema.h"
#include"rapidjson/stream.h"
#include"rapidjson/stringbuffer.h"
#include"rapidjson/uri.h"
#include"rapidjson/writer.h"
using namespace rapidjson;

这里 rapidjson 为作用域;

​
#include "rapidjson/document.h"

using namespace rapidjson;

Document document;  创建DOM树

document.Parse(json);  加载解析的json文件

​

 那么现在该 JSON 就会被解析至 document 中,成为一棵 *DOM 树 *:

 

解析过程(也就是读取过程):

定义 dom  树
 
Document dom;//定义DOM树根

dom.Parse(str); //将解析的文本加载DOM树上 这里str必须为const char*

assert(dom.IsObject()); //断言数据类型 为树对象


举例:

 

{
    "hello": "world",
    "t": true ,
    "f": false,
    "n": null,
    "i": 123,
    "pi": 3.1416,
    "a": [1, 2, 3, 4]
}

让我们查询一下根 Object 中有没有 "hello" 成员。由于一个 Value 可包含不同类型的值,我们可能需要验证它的类型,并使用合适的 API 去获取其值。在此例中,"hello" 成员关联到一个 JSON String。

assert(document.HasMember("hello"));

assert(document["hello"].IsString());

printf("hello = %s\n", document["hello"].GetString());

结果:world

JSON True/False 值是以 bool 表示的。

assert(document["t"].IsBool());

printf("t = %s\n", document["t"].GetBool() ? "true" : "false");

结果:true

JSON Null 值可用 IsNull() 查询。

printf("n = %s\n", document["n"].IsNull() ? "null" : "?");

结果:null

JSON Number 类型表示所有数值。然而,C++ 需要使用更专门的类型。

assert(document["i"].IsNumber());

// 在此情况下,IsUint()/IsInt64()/IsUint64() 也会返回 true

assert(document["i"].IsInt());

printf("i = %d\n", document["i"].GetInt());

// 另一种用法: (int)document["i"]

assert(document["pi"].IsNumber());

assert(document["pi"].IsDouble());

printf("pi = %g\n", document["pi"].GetDouble());

结果:i = 123

结果:pi = 3.1416

JSON Array 包含一些元素。

// 使用引用来连续访问,方便之余还更高效。

​
const Value& a = document["a"];

assert(a.IsArray());

for (SizeType i = 0; i < a.Size(); i++) // 使用 SizeType 而不是 size_t

printf("a[%d] = %d\n", i, a[i].GetInt());

​

结果:

a[0] = 1

a[1] = 2

a[2] = 3

a[3] = 4

反解析过程(也就是写过程):

    char name[] = "LI HUA";
	string gender = "boy";
	vector<string> hobby = { "足球","篮球","电影" };
	map<string, double> score = { {"math",100},{"Chinese",86},{"English",85} };
	string Lover_name = "Xiao Hong";
	string Love_gender = "girl";
	vector<string> Lover_hobby = { "画画","跳舞","唱歌" };
	map<string, double> Lover_score = { {"数学", 78.5},{"语文", 89},{"英语", 90} };

开始写:

StringBuffer s;
定义缓冲buff 写入文件
Writer<StringBuffer> writer(s);
    writer.StartObject();


	writer.Key("name");
	writer.String(name);


	writer.Key("gender");
	writer.String(gender.c_str());


	writer.Key("hobby");
	writer.StartArray();
	for (const auto& item : hobby)
	{
		writer.String(item.c_str());
	}
	writer.EndArray();


	writer.Key("score");
	writer.StartObject();
	for (auto &item : Lover_score) {
		writer.Key((item.first).c_str());
		writer.Double(item.second);
	}
	writer.EndObject();




	writer.Key("lover");
	writer.StartObject();
	writer.Key("name");
	writer.String(Lover_name.c_str());
	writer.Key("gender");
	writer.String(Love_gender.c_str());

	writer.Key("hobby");
	writer.StartArray();
	for (auto &item : Lover_hobby) {
		writer.String((item.c_str()));
	}
	writer.EndArray();




	writer.Key("score");
	writer.StartObject();
	for (auto &item : Lover_score) {
		writer.Key((item.first).c_str());
		writer.Double(item.second);
	}
	writer.EndObject();




	writer.EndObject();

	writer.EndObject();//全局对象

	std::string outFileName = R"(C:\Users\dell\Desktop\document.json)";
	std::ofstream outfile(outFileName, std::ios::trunc);
	outfile << "\n";
	outfile << s.GetString();
	outfile.close();

结果展示:

 

 

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值