You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:35:33