JSON解码未知对象

huangapple go评论78阅读模式
英文:

JSON decode unknown object

问题

我正在尝试解码一个具有结构类型的 JSON 响应。我要解码的对象实例如下所示:

{
  "title": "Some Title",
  "views": 344,
  "profiles": {
      "customField": "somevalue",
      "customField2": "somevalue"
  }
}

Golang 的结构体如下所示:

type Topic struct {
  Title    string   `json:"title"`
  Views    string   `json:"views"`
  Profiles string   `json:"profiles"`
}

如你所见,"Profiles" 属性是一个字符串,因为 profiles 对象是未知的,它内部的字段可以动态定义。

我正在尝试使用以下代码进行解码:

json.NewDecoder(response.Body).Decode(result)

其中 result 的类型是 Topic,但是它不起作用。为了正确解码答案,"Profiles" 属性应该是什么类型?

谢谢!

英文:

I'm trying to decode a json response with a struct type. An instance of the object i'm trying to decode looks as follows:

{
  "title": "Some Title",
  "views": 344,
  "profiles": {
	  "customField": "somevalue",
	  "customField2:" :somevalue"
  }
}

The golang struct is the following:

type Topic struct {
  Title         string   `json:"title"`
  Views         string   `json:"views"`
  Profiles      string   `json:"profiles"`
}

As you can see, the "Profiles" attribute is a string, since the profiles object is unknown, as the fields inside it can be dinamically defined.

I'm trying to decode this with:

json.NewDecoder(response.Body).Decode(result) 

Where result is of type Topic, but isn't working. What type should the "Profiles" attribute be in order to correctly decoding the answer?

Thanks!

答案1

得分: 3

阅读评论后,很明显profiles的值可以是任何类型,因此我建议将Profiles类型声明为map[string]interface{}

修改后的代码如下:

type Topic struct {
  Title    string                   `json:"title"`
  Views    int32                    `json:"views"`
  Profiles map[string]interface{}   `json:"profiles"`
}

希望对你有帮助!

英文:

Reading the comment it's clear that profiles value could be of any type, for this reason I suggest you to declare the Profiles type as a map[string]interface{}.
Topic becomes:

type Topic struct {
  Title         string   `json:"title"`
  Views         int32   `json:"views"`
  Profiles      map[string]interface{}   `json:"profiles"`
}

答案2

得分: 0

请查看 https://github.com/mitchellh/mapstructure
自述文件中有你可能在寻找的答案。

问题是,如果你有一个根据特定字段稍微变化的配置或编码。

或许我们无法在没有先读取 JSON 中的 "type" 字段的情况下填充特定的结构。我们可以对 JSON 的解码进行两次遍历(先读取 "type",然后再读取剩下的内容)。然而,更简单的方法是将其解码为 map[string]interface{} 结构,读取 "type" 键,然后使用类似这个库的方法将其解码为正确的结构。

英文:

Check out https://github.com/mitchellh/mapstructure
The readme has an answer you probably look for.

> problem is if you have configuration or an encoding that changes slightly depending on specific fields.
>
> Perhaps we can't populate a specific structure without first reading the "type" field from the JSON. We could always do two passes over the decoding of the JSON (reading the "type" first, and the rest later). However, it is much simpler to just decode this into a map[string]interface{} structure, read the "type" key, then use something like this library to decode it into the proper structure.

答案3

得分: 0

如果配置文件可能会变化,你应该在这里使用json.RawMessage。在内部,它是一个[]byte,可以根据外部文档的值进行解组,例如,可以解组为其他类型。

请参阅https://golang.org/pkg/encoding/json/#RawMessage和示例。

英文:

If profiles can vary you should take json.RawMessage here. Internally it is a []byte which late can be unmarshalled into other types, e.g. depending on values of the outer document.

See https://golang.org/pkg/encoding/json/#RawMessage and the examples.

答案4

得分: 0

Profiles 应该是一个结构体,并且在容器初始化时进行初始化。在这种情况下,我假设它是一个状态,比如 Facebook 状态或推特。我在这里提供了一个示例:https://play.golang.org/p/tG90idakLP

请记得在开始解组之前,在新创建的状态中实例化新的 profiles。

英文:

The Profiles should be a struct and initiated along with the container, in this case I assume it's a Status, such as FB status or Tweet, I've made an example here https://play.golang.org/p/tG90idakLP

Remember to instantiate the new profiles inside a newly created status, before you start unmarshalling.

huangapple
  • 本文由 发表于 2017年2月24日 23:19:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/42442187.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定