我有一个接收JSON消息的应用。 JSON有各种各样的"部分" (以下示例)。每个部分都有一个名称,但除此之外的结构在每个部分完全不同。
我想要做的是仔细阅读各个部分,并将每个部分解组到适当的对象中。但奇怪的是我发现这很困难,因为看起来你可以将整个JSON解组成一个对象,或者你可以得到一个通用的map [string] interface {}。我发现的所有示例代码都进入了类型切换并手动分配变量......我希望将neato Unmarshal直接写入对象。
有没有办法为Unmarshal提供JSON的子集?我自己可以对字节[]进行切片和切块,但这看起来很可怕......当然其他人也经历过这样的事情?
这是我玩过的。
package main
import "encoding/json"
type Book struct {
Author string
Title string
Price float64
}
type Movie struct {
Title string
Year float64
Stars float64
Format string
}
var sections map[string]interface{}
func main() {
/*
* "Book" and "Movie" are "sections".
* There are dozens of possible section types,
* and which are present is not known ahead of time
*/
incoming_msg_string := `
{
"Book" : {
"Author" : "Jack Kerouac",
"Title" : "On the Road",
"Price" : 5.99
},
"Movie" : {
"Title" : "Sherlock Holmes vs. the Secret Weapon",
"Year" : 1940,
"Stars" : 2.5,
"Format" : "DVD"
}
}`
/*
* this code gets me a list of sections
*/
var f interface{}
err := json.Unmarshal([]byte(incoming_msg_string), &f)
if err != nil {
panic(err)
}
var list_of_sections []string
for section_type, _ := range f.(map[string]interface{}) {
list_of_sections = append(list_of_sections, section_type)
}
/*
* next I would like to take the JSON in the "book" section
* and unmarshal it into a Book object, then take the JSON
* in the "movie" section and unmarshal it into a Movie object,
* etc.
*
* https://blog.golang.org/json-and-go has an example on
* decoding arbitrary data, but there's only one Unmarshaling.
*
* json.RawMessage has an example in the docs but it assumes
* the objects are the same type (I think). My attempts to use
* it with a two-field struct (section name, and a raw message)
* gave runtime errors. Likewise unmarshaling into a
* []json.RawMessage gave "panic: json: cannot unmarshal object into Go value of type []json.RawMessage"
*
* What I'm looking for is something like:
* json.Unmarshal(some_json["a certain section"],&object)
*
*/
}
任何面包屑痕迹都暗示非常感激。
答案 0 :(得分:4)
对type Sections map[string]json.RawMessage
变量进行初始解组。然后,您将获得与其关联的节类型和原始数据。您可以打开部分类型并解组到特定的部分结构,也可以解组为map [string] interface {}并一般地处理它们。 (无论什么最适合您的应用。)