Golang Json 解组多个动态命名字段

时间:2021-04-16 03:05:10

标签: json go struct unmarshalling decoding

我有以下需要解码的 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,我想我可以像往常一样映射它。

2 个答案:

答案 0 :(得分:3)

一种选择可能是延迟解析,直到您知道类型;类似于以下内容 (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 文档解释了这一点?

答案 1 :(得分:1)

我会这样做:

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 也能工作。