英文:
How to unmarshal dynamic json objects with Golang
问题
让我先告诉你,我在Go世界中还是相对新手。
我想做的是读取我从一个JSON API(我无法控制)获取的JSON数据。一切都运行良好,我可以显示接收到的ID和标签。但是,fields字段有点不同,因为它是一个动态数组。
我可以从API接收到这样的数据:
{
"id":"M7DHM98AD2-32E3223F",
"tags": [
{
"id":"9M23X2Z0",
"name":"History"
},
{
"id":"123123123",
"name":"Theory"
}
],
"fields": {
"title":"项目标题",
"description":"项目描述"
}
}
或者,我可能只接收到description
而没有title
,或者接收到另一个随机对象,比如long_title
。返回的对象可能完全不同,并且可以是无限多种可能的对象。但它们总是返回一个带有键和字符串内容的对象,就像示例中的那样。
这是我目前的代码:
type Item struct {
ID string `json:"id"`
Tags []Tag `json:"tags"`
//Fields []Field `json:"fields"`
}
// 调用返回的标签数据
type Tag struct {
ID string `json:"id"`
Name string `json:"name"`
}
// AllEntries 从会话中获取所有条目
func AllEntries() {
resp, _ := client.Get(APIURL)
body, _ := ioutil.ReadAll(resp.Body)
item := new(Item)
_ = json.Unmarshal(body, &item)
fmt.Println(i, "->", item.ID)
}
所以Item.Fields是动态的,无法预测将是什么键名,因此据我所知,无法为其创建一个结构体。但是,我对Go还是相当新手,有人能给我一些建议吗?谢谢
英文:
let me start by telling that I'm pretty recent in the Go world.
What I'm trying to do is to read the json I get from a JSON API (I don't control). Everything is working fine, I can show the received ID and Tags too. But the fields field is a little bit different, because its a dynamic array.
I can receive from the api this:
{
"id":"M7DHM98AD2-32E3223F",
"tags": [
{
"id":"9M23X2Z0",
"name":"History"
},
{
"id":"123123123",
"name":"Theory"
}
],
"fields": {
"title":"Title of the item",
"description":"Description of the item"
}
}
Or instead of title
and description
I could receive only description
, or receive another random object like long_title
. The objects return may differ completly and can be an infinite possibility of objects. But it always returns objects with a key and a string content like in the example.
This is my code so far:
type Item struct {
ID string `json:"id"`
Tags []Tag `json:"tags"`
//Fields []Field `json:"fields"`
}
// Tag data from the call
type Tag struct {
ID string `json:"id"`
Name string `json:"name"`
}
// AllEntries gets all entries from the session
func AllEntries() {
resp, _ := client.Get(APIURL)
body, _ := ioutil.ReadAll(resp.Body)
item := new(Item)
_ = json.Unmarshal(body, &item)
fmt.Println(i, "->", item.ID)
}
So the Item.Fields is dynamic, there is no way to predict what will be the key names, and therefore as far I can tell, there is no way to create a struct for it. But again, I'm pretty newbie with Go, could someone give me any tips? Thanks
答案1
得分: 7
如果"fields"
中的数据始终是一个平面字典,那么可以将Fields
的类型设置为map[string]string
。
对于任意数据,请将Fields
指定为RawMessage
类型,并根据其内容稍后进行解析。文档中的示例:https://play.golang.org/p/IR1_O87SHv
如果字段的变化太不可预测,那么可以保持该字段为[]byte
,或者如果有一些字段始终是常见的,那么可以解析这些字段并忽略其他字段(但这将导致丢失其他字段中的数据)。
英文:
If the data in "fields"
is always going to be a flat-dict then you can use map[string]string
as type for the Fields
.
For arbitrary data specify Fields
as a RawMessage
type and parse it later on based on its content. Example from docs: https://play.golang.org/p/IR1_O87SHv
If the fields are way too unpredictable then you can keep this field as is([]byte
) or if there are fields that are always going to common then you can parse those and leave the rest(but this would result in loss of data present in other fields).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论