如何使用Rapidjson将一个JSON文档的jVal1Key1替换为另一文档的对应键值
解决RapidJSON中替换JSON节点的问题
先理清楚你的需求:把Json 1里jKey1下的jVal1Key1节点,替换成Json 2中整个jVal1Key1节点的内容。先说说你现有代码里的几个小问题,再给你完整的可运行实现方案。
现有代码的潜在问题
- 重复调用了
Parse方法:第一次调用Parse<0>(...).HasParseError()根本没做有效的错误处理,第二次又调用Parse会覆盖之前的解析状态 - 缺少解析错误检查:一旦JSON格式有问题,后续操作直接会崩溃
- 忽略了RapidJSON的内存规则:跨Document的节点不能直接赋值,必须用
CopyFrom方法完成节点复制
完整实现代码
#include "rapidjson/document.h" #include "rapidjson/writer.h" #include "rapidjson/stringbuffer.h" #include <iostream> #include <string> using namespace rapidjson; int main() { std::string json1 = R"({"jKey1":{"jVal1Key1":{"mystr":["str1","str2"]},"jVal2Key2":["data1","data2"]},"jKey2":"Title"})"; std::string json2 = R"({"jVal1Key1":{"mystr":["str1","str2"]}})"; // 解析Json1并处理解析错误 Document doc1; if (doc1.Parse(json1.c_str()).HasParseError()) { std::cerr << "Json1解析失败,错误码:" << doc1.GetParseError() << ",错误位置:" << doc1.GetErrorOffset() << std::endl; return 1; } // 解析Json2并处理解析错误 Document doc2; if (doc2.Parse(json2.c_str()).HasParseError()) { std::cerr << "Json2解析失败,错误码:" << doc2.GetParseError() << ",错误位置:" << doc2.GetErrorOffset() << std::endl; return 1; } // 检查Json1中目标节点路径是否存在且类型正确 if (!doc1.HasMember("jKey1") || !doc1["jKey1"].IsObject() || !doc1["jKey1"].HasMember("jVal1Key1")) { std::cerr << "Json1中找不到目标节点 jKey1->jVal1Key1" << std::endl; return 1; } // 检查Json2中待替换的节点是否存在且类型正确 if (!doc2.HasMember("jVal1Key1") || !doc2["jVal1Key1"].IsObject()) { std::cerr << "Json2中找不到节点 jVal1Key1" << std::endl; return 1; } // 执行节点替换:用CopyFrom完成跨Document的节点复制 doc1["jKey1"]["jVal1Key1"].CopyFrom(doc2["jVal1Key1"], doc1.GetAllocator()); // 输出修改后的Json1 StringBuffer buffer; Writer<StringBuffer> writer(buffer); doc1.Accept(writer); std::cout << "修改后的JSON结果:\n" << buffer.GetString() << std::endl; return 0; }
关键细节解释
- 解析错误校验:每次调用
Parse后必须检查HasParseError(),这是避免程序崩溃的基础操作 - 节点合法性检查:操作节点前要确认对应的Member存在、类型匹配(比如是Object类型),防止访问空节点导致未定义行为
- CopyFrom的必要性:RapidJSON的Value归属于创建它的Document,跨Document直接赋值会导致内存错误,必须用
CopyFrom并传入目标Document的Allocator,才能在目标内存池中生成新的节点内容
运行这段代码后,就能实现你想要的节点替换效果了。
内容的提问来源于stack exchange,提问作者Smith Dwayne
相关产品推荐
相关产品推荐

