RapidJSON教程:从DOM解析到JSON操作全解析
rapidjson 项目地址: https://gitcode.com/gh_mirrors/rap/rapidjson
前言
RapidJSON是一个高效的C++ JSON解析器和生成器库,以其卓越的性能和简洁的API著称。本教程将通过一个完整的示例代码,深入讲解RapidJSON的核心功能和使用方法,帮助开发者快速掌握这一强大工具。
环境准备
使用RapidJSON前需要包含相关头文件:
#include "rapidjson/document.h" // DOM风格的API
#include "rapidjson/prettywriter.h" // 用于格式化输出JSON
1. JSON解析
RapidJSON提供两种解析JSON字符串的方式:
常规解析
Document document;
if (document.Parse(json).HasParseError())
return 1;
原地解析(In-situ)
char buffer[sizeof(json)];
memcpy(buffer, json, sizeof(json));
if (document.ParseInsitu(buffer).HasParseError())
return 1;
原地解析的优势在于直接修改输入字符串,避免了额外的内存分配,性能更高,但会破坏原始字符串。
2. 访问JSON数据
解析完成后,可以通过DOM API访问JSON中的各个值:
基本类型访问
// 字符串
assert(document["hello"].IsString());
printf("hello = %s\n", document["hello"].GetString());
// 布尔值
assert(document["t"].IsBool());
printf("t = %s\n", document["t"].GetBool() ? "true" : "false");
// 数字
assert(document["i"].IsInt());
printf("i = %d\n", document["i"].GetInt());
// 浮点数
assert(document["pi"].IsDouble());
printf("pi = %g\n", document["pi"].GetDouble());
数组遍历
const Value& a = document["a"];
for (SizeType i = 0; i < a.Size(); i++)
printf("a[%d] = %d\n", i, a[i].GetInt());
对象成员遍历
static const char* kTypeNames[] = { "Null", "False", "True", "Object", "Array", "String", "Number" };
for (Value::ConstMemberIterator itr = document.MemberBegin(); itr != document.MemberEnd(); ++itr)
printf("Type of member %s is %s\n", itr->name.GetString(), kTypeNames[itr->value.GetType()]);
3. 修改JSON数据
RapidJSON提供了丰富的API来修改DOM树:
修改现有值
document["i"] = 2432902008176640000ULL; // 修改为20的阶乘
向数组添加元素
Value& a = document["a"];
Document::AllocatorType& allocator = document.GetAllocator();
for (int i = 5; i <= 10; i++)
a.PushBack(i, allocator);
添加字符串成员
// 简单字符串赋值
document["hello"] = "rapidjson";
// 需要分配内存的字符串
Value author;
char buffer2[10];
int len = sprintf(buffer2, "%s %s", "Milo", "Yip");
author.SetString(buffer2, len, document.GetAllocator());
document.AddMember("author", author, document.GetAllocator());
4. 生成JSON字符串
使用PrettyWriter可以生成格式化的JSON字符串:
StringBuffer sb;
PrettyWriter<StringBuffer> writer(sb);
document.Accept(writer);
puts(sb.GetString());
最佳实践
-
内存管理:RapidJSON使用分配器(Allocator)管理内存,修改DOM时通常需要传递文档的分配器。
-
性能优化:
- 对于静态字符串,使用
SetString(const char*)
避免拷贝 - 对于动态字符串,使用带分配器的
SetString
确保内存安全
- 对于静态字符串,使用
-
类型安全:始终检查值的类型(IsXXX())后再进行操作
-
迭代器使用:遍历大型对象或数组时,使用迭代器(ConstMemberIterator/ConstValueIterator)效率更高
总结
本教程通过一个完整的示例展示了RapidJSON的核心功能,包括JSON解析、数据访问、修改和序列化。RapidJSON的API设计简洁高效,特别适合对性能要求较高的应用场景。掌握这些基础知识后,开发者可以轻松地在C++项目中集成JSON处理功能。
对于更高级的用法,如自定义分配器、流式处理等,可以参考RapidJSON的官方文档进一步学习。
rapidjson 项目地址: https://gitcode.com/gh_mirrors/rap/rapidjson
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考