如何解析动态类型的 json?

2022-11-11 15:42:38 +08:00
 gam2046

样例

{
    "video": [
        1,
        2,
        3
    ],
    "video": {
        "a": {
            "aa": []
        }
    },
    "video_type": "template_a"
}

需求

就像样例中那样,video 字段的类型有好几种,具体哪种是通过 video_type 字段决定。

那么对于这种样子的 json ,使用 Golang 应该如何优雅的解析呢?

(问为什么设计成样子的结构,以及解决方案是修改 json 的算了,人家已经定义好了,跑了好几年,不可能因为我改)

2908 次点击
所在节点    Go 编程语言
18 条回复
sardina
2022-11-11 16:13:42 +08:00
先写一个结构体来解析对应的 video type 然后根据不同的 type 去用不同的结构体去解析 video 字段
或者使用一个叫 gjson 的库试试
lisongeee
2022-11-11 16:15:40 +08:00
如果是 kotlin 可以用 密封类,如果是 typescript 可以用联合类型,如果是 go ,我不到啊
iamzuoxinyu
2022-11-11 16:38:22 +08:00
用 DOM 风格的 json 解析库。
virusdefender
2022-11-11 16:40:32 +08:00
先解析到只有一个字段 video_type 的 struct 上,然后判断类型后选择对应的 struct 再解析
rrfeng
2022-11-11 16:41:27 +08:00
如果每种 video 类型的格式固定,那就好办了

把 video 字段定义为 json.RawMessage ,然后根据 type 再进一步 Unmarshal 即可。
Ritter
2022-11-11 16:42:25 +08:00
把 video_type 对应的 struct 都枚举出来
dzdh
2022-11-11 16:48:23 +08:00
go 的话,gjson 类似的库?

if x.Get("XX").IsArray IsFloat / x.Get("XX").Array()[0].IsFloat/IsArray
aw2350
2022-11-11 16:52:45 +08:00
gjson \ jsonparser
Privileges
2022-11-11 16:54:25 +08:00
用 gjson 解析很方便
Crawping
2022-11-11 17:19:40 +08:00
用 map[string]interface{} 根据 template 解析
petercui
2022-11-11 17:21:57 +08:00
Jackson 的话,继承 JsonDeserializer 然后自己一个字段一个字段的解析就行了。
yulon
2022-11-11 17:22:15 +08:00
Go 的 interface 和 map[string] 不是万能的?别的语言还要考虑塞个变体
yeqown
2022-11-11 17:26:52 +08:00
#5 正解,文档里的 example 和你的场景完全一致 https://pkg.go.dev/encoding/json#example-RawMessage-Unmarshal
Great233
2022-11-11 17:27:28 +08:00
lisxour
2022-11-11 17:41:11 +08:00
我用的 github.com/bitly/go-simplejson ,然后使用 simplejson.NewJson(bytes)反序列化,接着用 GetXXX 、SetXXX
lisxour
2022-11-11 17:46:00 +08:00
不需要定义任何结构体,可参考官方例子: https://github.com/bitly/go-simplejson/blob/master/simplejson_test.go
sbex
2022-11-11 17:59:23 +08:00
pkoukk
2022-11-11 18:24:52 +08:00
先把 json decode 到 map[string]any
然后 switch m[video_type]
最后用 mapstructure 把 m[video] decode 到对应的 Struct

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/894502

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX