【问题标题】:Golang Json unmarshaling with multiple dynamically named fieldsGolang Json 使用多个动态命名字段解组
【发布时间】:2021-07-11 02:04:09
【问题描述】:

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

【问题讨论】:

  • 这真的取决于您希望从中获得什么以及您将如何使用它。有几种不同的方法

标签: json go struct unmarshalling decoding


【解决方案1】:

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

【讨论】:

  • 最终它将用于数据抓取。我可以将未编组的 json 映射到我编写的导出器函数。问题最初是我找不到映射任何东西的方法,因为 Card:ID 等对象是唯一的。对于此示例,打印效果很好,但如果您有任何其他建议,我很乐意听到它们,因为我对 Go 非常陌生。
  • @StevenPenny 的回答也可以解决问题;它实际上取决于文件的完整结构以及是否需要将其拆分为不同的结构(如果不这样做会更简单一些)。我需要更多信息来提出更详细的建议,但此处显示的技术应该可以帮助您入门(下一步是确定下一步需要采用什么格式的数据;例如,存储在数据库中等)。跨度>
【解决方案2】:

我会这样做:

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 也可以。

【讨论】:

    猜你喜欢
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多