不使用结构体进行JSON反序列化

15

我有以下的JSON

[{"href":"/publication/192a7f47-84c1-445e-a615-ff82d92e2eaa/article/b;version=1493756861347"},{"href":"/publication/192a7f47-84c1-445e-a615-ff82d92e2eaa/article/a;version=1493756856398"}]

根据给定的答案,我尝试了以下操作

var objmap map[string]*json.RawMessage
err := json.Unmarshal(data, &objmap)

我得到了一个空数组和以下错误。有什么建议吗?

json: 无法将数组反编组为类型为 map[string]*json.RawMessage 的Go值

3个回答

20

您可以按以下方式取消封送到一个[]map[string]interface{}

data := []byte(`[{"href":"/publication/192a7f47-84c1-445e-a615-ff82d92e2eaa/article/b;version=1493756861347"},{"href":"/publication/192a7f47-84c1-445e-a615-ff82d92e2eaa/article/a;version=1493756856398"}]`)
var objmap []map[string]interface{}
if err := json.Unmarshal(data, &objmap); err != nil {
    log.Fatal(err)
}
fmt.Println(objmap[0]["href"]) // to parse out your value

要了解更多有关unmarshalling的工作原理,请参阅此处: https://godoc.org/encoding/json#Unmarshal


它适用于嵌套对象吗? - Santosh Kumar

3

这不是直接的答案,但我认为非常有用

无需结构体进行Json反序列化和缩进


func JsonIndent (jsontext []byte) ([]byte,error) {
    var err error
    var jsonIndent []byte
    var objmap map[string]*json.RawMessage
    err = json.Unmarshal(jsontext, &objmap)
    if err != nil {
        return jsonIndent,err
    }
    jsonIndent, err = json.MarshalIndent(objmap,"", "  ")
    return jsonIndent,err
}

1
你的 json 是一个对象数组,在 Go 中,encoding/json 包将 maps 编组/解组为 json 的 对象 而不是数组,因此你可能需要分配一个 map的切片
var objs []map[string]*json.RawMessage
if err := json.Unmarshal([]byte(data), &objs); err != nil {
    panic(err)
}

https://play.golang.org/p/3lieuNkoUU

如果您不想使用切片,您可以将json数组包装在对象中。
var dataobj = `{"arr":` + data + `}`
var objmap map[string]*json.RawMessage
if err := json.Unmarshal([]byte(dataobj), &objmap); err != nil {
    panic(err)
}

https://play.golang.org/p/XM8MmV0gbc


谢谢澄清,我仍需要更多帮助。如果您可以的话,请在反序列化后也打印对象。 - user2727195
你是说要打印json.RawMessage对象吗? 如果是这样,那么json.RawMessage只是一个字节片,因此您可以将其打印为此类,例如https://play.golang.org/p/jeCU6PIWYv。但我想知道,您真的想使用[json.RawMessage](https://golang.org/pkg/encoding/json/#RawMessage)吗? 它的目的是允许您延迟解码(或预编码)json…如果您不需要这两个功能,最好使用具体类型。 - mkopriva
如果您不需要预计算/延迟的东西@user2727195,您应该使用类似于这样的东西:https://play.golang.org/p/VKf7HgAAID - mkopriva

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接