c++ nlohmann/json高级用法 c++如何使用json patch和json pointer

阿宇酱_2721

阿宇酱_2721

2026-03-22

433人浏览

原创

使用 json::patch() 进行局部更新需传入符合 rfc 6902 的 json patch 数组,path 必须为合法 json pointer(如 "/name"),特殊字符 / 和 ~ 需转义为 ~1 和 ~0,原数据与 patch 均须先 parse。

c++ nlohmann/json高级用法 c++如何使用json patch和json pointer

怎么用 json_patch 做局部更新而不破坏原结构

直接调用 json::patch() 是最简方式,但它要求 patch 文档本身是合法的 JSON Patch 格式数组(RFC 6902),不是任意对象。常见错误是传入一个普通 json 对象,结果静默失败或抛出 parse_error。

使用场景:服务端接收前端发来的部分字段更新请求(比如只改用户头像和昵称),不想反序列化整个对象再赋值。

  • patch 数据必须是 json 类型的数组,每个元素是带 "op"、"path"、"value" 的对象
  • "path" 必须是合法 JSON Pointer(如 "/name"、"/tags/0"),不能写成 "name" 或 "$.name"
  • 原数据和 patch 都要先用 json::parse() 解析,不能混用字符串和 json 对象
auto original = nlohmann::json::parse(R"({"name":"Alice","age":30})");
auto patch = nlohmann::json::parse(R"([
  {"op":"replace","path":"/name","value":"Bob"},
  {"op":"add","path":"/email","value":"bob@example.com"}
])");
auto result = original.patch(patch); // 返回新 json,original 不变

json_pointer 字符串怎么写才不越界或解析失败

JSON Pointer 本质是路径表达式,不是 XPath 或 CSS 选择器。最容易踩的坑是斜杠处理和特殊字符转义——比如键名含 / 或 ~,必须分别转为 ~1 和 ~0,否则 json_pointer 构造时直接抛 parse_error。

使用场景:从嵌套很深的配置里取某个开关字段,或动态拼接 path 做条件读取。

  • 根路径写 ""(空字符串),不是 "/";"/" 表示 key 为空的对象成员
  • 访问数组第 i 项用 "/items/0",不能用 "/items[0]" 或 "/items.0"
  • 运行时拼接 path 要手动转义:遇到 ~ 替换为 ~0,遇到 / 替换为 ~1
auto j = nlohmann::json::parse(R"({"a/b":{"c":"val"},"d~e":42})");
auto ptr1 = nlohmann::json_pointer("/a~1b/c"); // 注意 ~1
auto ptr2 = nlohmann::json_pointer("/d~0e");     // 注意 ~0
std::cout 

<h3>为什么 <code>patch()</code> 后丢失类型信息或精度</h3>
<p><code>json::patch()</code> 内部会做一次深拷贝 + 合并,所有数字默认按 double 存储,整数如 <code>123</code> 可能变成 <code>123.0</code>;bool 和 null 也可能在 patch 过程中被隐式转换。这不是 bug,而是 nlohmann/json 的设计取舍:它优先保证 JSON 标准兼容性,而非 C++ 原生类型保真。</p><div class="aritcle_card flexRow artxards">
											<div class="artcardd flexRow">
												<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2823" title="C++14"><img
														src="https://img.php.cn/upload/manual/001/431/639/6ac8b33c327c4749.png" alt="C++14" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
												<div class="aritcle_card_info flexColumn">
													<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="overflowclass">C++14</a>
													<p class="overflowclass">C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。</p>
												</div>
												<a rel="nofollow" href="/xiazai/gongju/2823" title="C++14" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
												</a>
											</div>
										</div>
<p>性能影响:每次 <code>patch()</code> 都触发完整遍历,对超大文档(>10MB)会有明显延迟,且无法流式处理。</p>
  • 如果必须保持整数精度,补丁前先用 j["field"].is_number_integer() 检查,再手动赋值
  • 避免对同一对象反复 patch:先 accumulate 所有操作到一个 patch 数组,再单次调用
  • 不支持原子性回滚 —— 如果 patch 中间某步失败,前面已生效的操作不会撤销

如何安全地组合 json_pointer 和 patch 做条件更新

直接把 json_pointer 当字符串拼进 patch 的 "path" 字段没问题,但要注意:pointer 实例本身不校验目标是否存在,而 patch() 在执行 "remove" 或 "replace" 时,若 path 不存在会抛 out_of_range 异常。线上服务不捕获就崩。

真实需求往往是“如果字段存在就更新,不存在就跳过”,但标准 patch 没这个语义。

  • 先用 contains() 或 at() + try/catch 预检路径有效性,再决定是否生成 patch
  • 不要依赖 patch() 的返回值判断成功与否 —— 它总返回新对象,异常才是失败信号
  • 对用户可控输入的 path,务必用 json_pointer::parse() 验证合法性,防止注入类似 "/../password" 的非法路径(虽然 JSON Pointer 规范不支持 ..,但解析器可能不严格)

复杂点在于:JSON Pointer 的“存在性”和 patch 的“可操作性”是两层检查,漏掉任何一层都可能让服务在边界 case 下挂掉。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2023.08.07

2095

5

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.23

3142

1

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

2023.10.13

1056

3

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

2025.09.10

3579

7

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

2023.09.22

549

3

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

2024.03.01

1678

6

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1698

5

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

2604

5

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

2023.10.24

6024

49

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习