Neatbo.

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}

完成前的检查清单

  • 比较结构和值,不仅比较格式化文字。
  • 还原后检查空数组和空对象。
  • 在浮点解析器可能舍入之前保留数字标记。
  • 对于重复键应明确拒绝,而不是猜测保留哪个值。

参考资料

本文相关工具

JSON 扁平化与还原 →将嵌套 JSON 展开为可还原的 JSON Pointer 路径,也能把点路径对象还原为嵌套对象。JSON Pointer 提取 →使用 RFC 6901 路径精确提取某个 JSON 值。JSON 格式化与转义 →排版或压缩严格 JSON、排序对象键,并编码或解码字符串,保留数字原文。