Golang Json 使用多个动态命名字段解组
Golang Json unmarshaling with multiple dynamically named fields
我有以下 Json 结构需要解码,但我不确定正确的方法
解组它。
var b = []byte(`{
"Card:5417871461137421886": {
"applicationUUID": "5417871461137421886",
"commit": "test_commit",
"lastSeen": "test_lastSeen",
"localUUID": "E4:F5:13:8E:F5:43",
"progress": "3.5",
"externalUUID": "test_externalUUID",
"state": "test_state"
},
"Card:5417871461137421886.Color": {
"applicationUUID": "5417871461137421886",
"color": "blue"
}
}`)
我最初的方法是以某种方式创建一个结构,然后解组到该结构,但由于动态性质,我不确定如何实现这一点。我尝试过的一种方法是使用并行结构,但是我也没有成功地使它正常工作。我有点不知道解决这个问题的好方法你可以在这里看到我的示例代码 https://play.golang.org/p/mzMArgo8ta2
我无法更改 Json 的结构,因为它是从 API 中读取的。最终我不想也不关心唯一的字段名称,因为应用程序 ID 总是作为一个值列出。如果有一个简单的方法来删除所有 Card:Id 我想我可以像正常一样映射它。
一个选项可能是延迟解析,直到你知道类型;类似于以下内容 (playground):
devices := make(map[string]json.RawMessage)
err := json.Unmarshal(b, &devices)
if err != nil {
log.Fatal(err)
}
for key, jsonVal:= range devices {
if len(key) > 5 && key[:5] == "Card:" {
var dev Device
err := json.Unmarshal(jsonVal, &dev)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%#v\n", dev)
} else if len(key) > 6 && key[:6] == "Color:" {
var oth Other
err := json.Unmarshal(jsonVal, &oth)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%#v\n", oth)
}
}
注意:不清楚您想对数据做什么,所以我现在只是打印结构。它也不太清楚如何识别每个元素的类型(您问题中的示例与示例代码中的示例不同);可能有一些关于 API 的文档可以解释这一点?
我会这样做:
package main
import (
"encoding/json"
"fmt"
)
const s = `
{
"Card:5417871461137421886": {
"applicationUUID": "5417871461137421886",
"commit": "test_commit",
"externalUUID": "test_externalUUID",
"lastSeen": "test_lastSeen",
"localUUID": "E4:F5:13:8E:F5:43",
"progress": "3.5",
"state": "test_state"
},
"Card:5417871461137421886.Color": {
"applicationUUID": "5417871461137421886",
"color": "blue"
}
}
`
func main() {
var m map[string]struct {
ApplicationUUID, Color, Commit, ExternalUUID, LastSeen, LocalUUID string
Progress, State string
}
json.Unmarshal([]byte(s), &m)
fmt.Printf("%+v\n", m)
}
但似乎 map[string]map[string]string
也可以。
我有以下 Json 结构需要解码,但我不确定正确的方法 解组它。
var b = []byte(`{
"Card:5417871461137421886": {
"applicationUUID": "5417871461137421886",
"commit": "test_commit",
"lastSeen": "test_lastSeen",
"localUUID": "E4:F5:13:8E:F5:43",
"progress": "3.5",
"externalUUID": "test_externalUUID",
"state": "test_state"
},
"Card:5417871461137421886.Color": {
"applicationUUID": "5417871461137421886",
"color": "blue"
}
}`)
我最初的方法是以某种方式创建一个结构,然后解组到该结构,但由于动态性质,我不确定如何实现这一点。我尝试过的一种方法是使用并行结构,但是我也没有成功地使它正常工作。我有点不知道解决这个问题的好方法你可以在这里看到我的示例代码 https://play.golang.org/p/mzMArgo8ta2
我无法更改 Json 的结构,因为它是从 API 中读取的。最终我不想也不关心唯一的字段名称,因为应用程序 ID 总是作为一个值列出。如果有一个简单的方法来删除所有 Card:Id 我想我可以像正常一样映射它。
一个选项可能是延迟解析,直到你知道类型;类似于以下内容 (playground):
devices := make(map[string]json.RawMessage)
err := json.Unmarshal(b, &devices)
if err != nil {
log.Fatal(err)
}
for key, jsonVal:= range devices {
if len(key) > 5 && key[:5] == "Card:" {
var dev Device
err := json.Unmarshal(jsonVal, &dev)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%#v\n", dev)
} else if len(key) > 6 && key[:6] == "Color:" {
var oth Other
err := json.Unmarshal(jsonVal, &oth)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%#v\n", oth)
}
}
注意:不清楚您想对数据做什么,所以我现在只是打印结构。它也不太清楚如何识别每个元素的类型(您问题中的示例与示例代码中的示例不同);可能有一些关于 API 的文档可以解释这一点?
我会这样做:
package main
import (
"encoding/json"
"fmt"
)
const s = `
{
"Card:5417871461137421886": {
"applicationUUID": "5417871461137421886",
"commit": "test_commit",
"externalUUID": "test_externalUUID",
"lastSeen": "test_lastSeen",
"localUUID": "E4:F5:13:8E:F5:43",
"progress": "3.5",
"state": "test_state"
},
"Card:5417871461137421886.Color": {
"applicationUUID": "5417871461137421886",
"color": "blue"
}
}
`
func main() {
var m map[string]struct {
ApplicationUUID, Color, Commit, ExternalUUID, LastSeen, LocalUUID string
Progress, State string
}
json.Unmarshal([]byte(s), &m)
fmt.Printf("%+v\n", m)
}
但似乎 map[string]map[string]string
也可以。