在golang中解析扁平和嵌套的JSON数据。

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

Unmarshall both flat and nested jsons in golang

问题

假设我想处理以下形式的嵌套和非嵌套的json,就像这个例子中一样:

source_json_1 := `{"owner": "John", "nickname": "Rose", "species": "Dog"}`
source_json_2 := `{"owner": "Doe", "Pet": [{"nickname": "Rose", "species": "Dog"},
			                              {"nickname": "Max", "species": "Cat"}]}`

如果我将Pet定义为嵌入的结构体,我可以轻松地进行解组:

type Owner struct {
	Name string
	Pet
}

type Pet struct {
	NickName	string
	Species		string
}

这样就可以正确地解组John的宠物。

{John {Rose Dog}}
{Doe { }}

但是,由于Pet实际上也可以是Pet的切片,Doe的Pet没有被正确解组。如果改为:

type Owner struct {
	Name string
	Pet  []Pet
}

那么Doe就会被正确解组。

{John []}
{Doe [{Rose Dog} {Max Cat}]}

如何同时处理这两种情况呢?

我更倾向于最终将其解组为Pet的切片,无论如何。

英文:

Say I want to be able to handle both nested and unnested jsons of the following form, as in this example:

source_json_1 := `{"owner": "John", "nickname": "Rose", "species": "Dog"}`
source_json_2 := `{"owner": "Doe", "Pet": [{"nickname": "Rose", "species": "Dog"},
			                              {"nickname": "Max", "species": "Cat"}]}`

If I define Pet as an embedded struct I can easily unmarshal it with:

type Owner struct {
	Name string
	Pet
}

type Pet struct {
	NickName	string
	Species		string
}

Resulting in John's pet getting adequately marshalled.

{John {Rose Dog}}
{Doe { }}

But since Pet can actually also be a slice of Pets, Doe's Pets are not correctly unmarshalled. If instead go with

type Owner struct {
	Name string
	Pet  []Pet
}

Then Doe gets marshalled just fine.

{John []}
{Doe [{Rose Dog} {Max Cat}]}

How can I catch both cases?

I'd prefer to marshall it into a slice of Pets in the end, no matter what.

答案1

得分: 2

你正在查看两个不同的数据结构,所以要使用单个struct类型对它们进行解组,你需要考虑两者:

type Owner struct {
    Name string
    Pet
    Pets []Pet `json:"Pet"`
}

然后,如果你希望切片是权威的,在解组后将嵌入的元素移动到切片中:

// owner := unmarshall blah blah
if owner.Pet != Pet{} {
    owner.Pets = append(owner.Pets, owner.Pet)
}
英文:

You're looking at two separate data structures, so to unmarshal them with a single struct type, you'd need to account for both:

type Owner struct {
    Name string
    Pet
    Pets []Pet `json:"Pet"`
}

Then, if you want the slice to be authoritative, after you unmarshall, move the embedded to the slice:

// owner := unmarshall blah blah
if owner.Pet != Pet{} {
    owner.Pets = append(owner.Pets, owner.Pet)
}

huangapple
  • 本文由 发表于 2017年6月17日 00:49:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/44594289.html
匿名

发表评论

匿名网友

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

确定