解组不一致的JSON

时间:2016-03-31 00:28:45

标签: json serialization go

我有这样的JSON(我无法控制):

{
    "foo1":{
        "a":{
             "up":10,
             "down":5
        }
    },
    "foo2":{
        "a":{
             "up":1,
             "down":1
        }
    },
    "bar":{
        "up":11,
        "down":6
    }
}

“foo1”和“foo2”是动态的。

如何在go中正确解组这个结构?

如果我可以告诉不要尝试反序列化“bar”(不一致的属性),那就没关系。

2 个答案:

答案 0 :(得分:3)

默认情况下,将忽略在您解组的结构中未指定的字段。

在这种情况下,您的结构将设置如下:

type NestedProp2 struct {
    Up   int
    Down int
}
type NestedProp struct {
    A NestedProp2
}
type Prop struct {
    Foo1 NestedProp
    Foo2 NestedProp
}

当你调用json.Unmarshal函数时,不会反序列化额外属性:

var prop Prop
err := json.Unmarshal(jsonBlob, &prop)
if err != nil {
    fmt.Println("error:", err)
}
fmt.Printf("%+v", prop)

所以你得到以下输出:

{Foo1:{A:{Up:10 Down:5}} Foo2:{A:{Up:1 Down:1}}}

您可以在行动here.

中看到它

答案 1 :(得分:0)

你说:

  

我有JSON(我无法控制)

那么你可以控制到什么程度?在这里,我可以为您提供一些方案,并希望其中一些符合您的目的:)

首先记住一般规则:

在Golang中,如果JSON键无法在struct中找到匹配的字段,则不会对其进行解组。

这意味着,对于JSON结构中的键名,当解组时,它将在不区分大小写的同一级别的同一级别的golang结构中查找字段。如果此搜索失败,则此密钥不会被解组。

例如,名为foo1的键将在同一缩进级别的golang结构中查找字段名foo1。但是,它也与Foo1FoO1匹配,因为此匹配不区分大小写。

请记住,您也可以使用字段标记来指定字段名称。请查看official page.

某些JSON字段的值不一致,可以忽略它们。

@gnalck在他的回答中解决了这个问题。根据一般规则,如果那些不一致的字段未找到匹配,则它们将不会被解组。因此,不要将这些不一致的字段放在结构中,你就可以了。

某些JSON字段的值不一致,但不能忽略它们。

在这种情况下,@gnalck失败,因为这些字段无法忽略。现在更好的方法是将bar解组为json.RawMessage,以便稍后解组。

JSON对象的键未确定,它们的值也未确定。

在这种情况下,我们可以将整个JSON对象解组为map[string]json.RawMessage,然后解组每个字段。解组到地图时,您可以遍历地图以获取所有字段,然后将它们解组为适当的结构。