JSON 扁平化如何避免丢数据:路径、空容器与大整数
用包含特殊键名、空数组和大整数的样例,解释点号路径为何不可靠,以及 containers/values 结构如何支持扁平化后的还原。
点号路径看起来简单,但并不唯一
对于 {"a.b":1} 和 {"a":{"b":1}},都写成 a.b 会丢失原始差异。键还可以包含斜线、波浪号,甚至空字符串。
JSON Pointer 为斜线和波浪号提供明确转义。使用标准路径可以减少歧义,但路径本身仍不足以表示所有容器信息。
还原操作已合并进 JSON 扁平化与还原工具;排序键位于 JSON 格式化与转义的“处理任务”选项中。
空容器和数字键需要额外信息
空数组中没有叶子值,如果只记录叶子路径,它可能在转换中消失。对象的 "0" 键也不应自动变成数组下标。
Neatbo 将 containers 和 values 分开输出。还原时先重建数组与对象,再填入对应路径的值,因此可以保留空容器。
数值精度需要从读取时保护
如果一个大整数在解析时就转成普通浮点数,后面再格式化也无法找回失去的数字。用于记录 ID 的值尤其需要注意。
这些 JSON 转换保留数字 token 原文,并拒绝同一个对象中的重复键。输出后仍应核对接收方的 JSON 解析方式,因为下游系统可能采用不同数值类型。
先用容易出问题的样例检查往返转换
下面的样例同时包含字面点号键、嵌套对象、带斜线的键、空数组,以及键名为“0”的对象。这些情况在简化的扁平表格里可能很相似,却属于不同 JSON 结构。
JSON Pointer 在路径片段内用 ~0 表示 ~,用 ~1 表示 /,点号没有特殊含义。在这个例子中,/a.b 访问字面键名,/a/b 访问嵌套值。开头的斜线引入一个片段,空指针表示整份文档。
Neatbo 的容器映射记录某个路径是对象还是数组,也记录空容器。这个信封结构是应用格式,并不是 JSON Pointer 标准本身的要求。应使用配套的还原工具,并核对重建数据后,再决定是否让其他系统采用这一表示。
| 目标值 | Pointer | 区别 |
|---|---|---|
| 字面键 a.b | /a.b | 点号仍是键名的一部分 |
| 嵌套的 b | /a/b | 两个路径片段 |
| 字面键 x/y | /x~1y | 斜线经过转义 |
| 对象键 0 | /labels/0 | 容器类型必须仍为对象 |
{"a.b":1,"a":{"b":2},"x/y":3,"empty":[],"labels":{"0":"zero"},"id":9007199254740993}完成前的检查清单
- 比较结构和值,不仅比较格式化文字。
- 还原后检查空数组和空对象。
- 在浮点解析器可能舍入之前保留数字标记。
- 对于重复键应明确拒绝,而不是猜测保留哪个值。
参考资料
- RFC 6901:JSON Pointer
定义指针路径和转义规则,不包含 Neatbo 的 containers/values 信封结构。