Go“冷门”库之ohler55/ojg,兼容性更好持续维护的JSONPath库

现在用 Go 写业务的越来越多了,虽然没有干倒 JAVA,但抢占了很多 PHP、Node、Python Web 的份额。不过由于 Go 相对来说时间较短,在生态上差一点,有些场景一下找不到现成的库。因此我打算出个Go“冷门”库系列,介绍一些项目中实际验证过的、但鲜为人知的库。期望更多人了解到这些库,使用后多给开源社区反馈。

在 JAVA 时代,XmlPath 特别流行,对应的就有 JSONPath,方便直接获取 JSON 中的值。在 Go 里有个特别出名的库 gjson 就是这个用处,但它没有按 JSONPath 规范实现,单独用没有问题,但要和别的模块(非Go)交互时就得使用大家都有的。json-path-comparison 上倒是有几款 Go 的库,但很多都年久失修,就剩 ohler55/ojgspyzhov/ajson 还在维护,当时选择了 ohler55/ojg,因为作者一直在做JSON相关的库,有成熟的 Ruby、C 的实现,看着经验非常丰富。

ojg 这个库,不仅仅只有 JSONPath 的功能还包含常规 JSON 库的 Marshal/Unmarshal,但这个赛道太卷了,后面有机会再介绍。这里主要介绍其 JSONPath 功能。使用上也很简单:

oj.ParseString 是将 JSON 字符串解析为 Go 内置结构,等价于 Unmarshal 为 any(你用其它库进行这一步也是可以的)。但和一般 JSON 库默认的行为不一样,会判断类型,特别是 int64(其它库默认是float64),转换为对应的数据类型:

jp.ParseString 则是生成提取规则(可以重复使用),应用于前面解析的 any 上,进行提取。用法可以说是非常简单。

特别的,按 JSONPath 设计,返回的结果是个数组,即使明确提取出来的是一个值,就像上面的例子,直觉的结果应该是4,不过所有库都这样。但如果就想返回4呢?不能直接取[0],因为JSONPath是支持切片操作的,list[0:1]仍然需要返回一个list。那如何判断了,好在 jp.ParseString 的规则有类型,可以判断最后一步操作是不是切片等。

另外,因为 JSONPath 设计比较粗糙或者说很多细节不清晰,所有很多库可能会不一致,比如我提的这个 issue,JSON key 中有 - 就必须用[]方式(["foo-bar"])提取了,不能用 .foo-bar。

所以相对 JSONPath 我更推荐 jmespath,它除了功能更强大,另外一个优点就是规范定义比较清晰,各个语言的库都是官方主导实现,这样更方便跨语言交互。不过 Go 的实现推荐使用 jmespath-community/go-jmespath 版本,还在持续维护。

CC BY-NC-SA 4.0

扫码分享

      复制标题+网址成功,请去要分享的地方粘贴

本 Blog 不支持评论,如有疑问或建议请联系我,以完善内容,期望帮助到更多的同学