英文:
Unmarshaling nest JSON response into nested struct
问题
这是我调用的Web API返回的示例JSON:
{
"Ability1": "有毒烟雾",
"AbilityId1": 7812,
"AttackSpeed": 0.86,
"Cons": "",
"HP5PerLevel": 0.47,
"Health": 360,
"Speed": 350,
"abilityDescription1": {
"itemDescription": {
"cooldown": "12s",
"cost": "60/70/80/90/100",
"description": "阿格尼在地面目标位置召唤一团有毒烟雾,每秒造成伤害。将阿格尼的任何技能释放到烟雾中会引爆气体,使半径内的所有敌人昏迷。",
"menuitems": [
{
"description": "技能:",
"value": "地面目标"
},
{
"description": "影响:",
"value": "敌人"
},
{
"description": "伤害:",
"value": "魔法"
},
{
"description": "半径:",
"value": "20"
}
],
"rankitems": [
{
"description": "每次伤害:",
"value": "10/20/30/40/50 (+5%魔法强度)"
},
{
"description": "烟雾持续时间:",
"value": "10秒"
},
{
"description": "昏迷持续时间:",
"value": "1秒"
}
],
"secondaryDescription": ""
}
},
"abilityDescription5": {
"itemDescription": {
"cooldown": "",
"cost": "",
"description": "在进行4次基础攻击后,阿格尼将获得一个增益效果。在下一次释放火焰波或火雨时,被这些技能击中的所有敌人还会被点燃,每0.5秒造成伤害,持续3秒。",
"menuitems": [
{
"description": "影响:",
"value": "敌人"
},
{
"description": "伤害:",
"value": "魔法"
}
],
"rankitems": [
{
"description": "每次伤害:",
"value": "5 (+10%魔法强度)"
}
],
"secondaryDescription": ""
}
},
"basicAttack": {
"itemDescription": {
"cooldown": "",
"cost": "",
"description": "",
"menuitems": [
{
"description": "伤害:",
"value": "34 + 1.5/等级 (+20%魔法强度)"
},
{
"description": "进展:",
"value": "无"
}
],
"rankitems": [],
"secondaryDescription": ""
}
},
"id": 1737,
"ret_msg": null
}
这是我定义的结构体:
type God struct {
Ability1 string
Ability2 string
Ability3 string
Ability4 string
Ability5 string
AbilityId1 int
AbilityId2 int
AbilityId3 int
AbilityId4 int
AbilityId5 int
Attack_speed float64
Attack_speed_per_level float64
Cons string
Hp5_per_level float64
Health int
Health_per_five int
Health_per_level int
Item1 string
Item2 string
Item3 string
Item4 string
Item5 string
Item6 string
Item7 string
Item8 string
Item9 string
ItemId1 int
ItemId2 int
ItemId3 int
ItemId4 int
ItemId5 int
ItemId6 int
ItemId7 int
ItemId8 int
ItemId9 int
Lore string
Mp5_per_level float64
Magic_protection int
Magic_protection_per_level int
Mana int
Mana_per_five float64
Mana_per_level int
Name string
On_free_rotation string
Pantheon string
Physical_power int
Physical_power_per_level int
Physical_protection int
Physical_protection_per_level float64
Pros string
Roles string
Speed int
Title string
Type string
Abilitydescription1 struct {
Item_description struct {
Cooldown string
Cost string
Description string
Menu_items struct {
Description string
Value string
}
Rank_items struct {
Description string
Value string
}
Secondary_description string
}
}
Ability_description2 struct {
Item_description struct {
Cooldown string
Cost string
Description string
Menu_items struct {
Description string
Value string
}
Rank_items struct {
Description string
Value string
}
Secondary_description string
}
}
Ability_description3 struct {
Item_description struct {
Cooldown string
Cost string
Description string
Menu_items struct {
Description string
Value string
}
Rank_items struct {
Description string
Value string
}
Secondary_description string
}
}
Ability_description4 struct {
Item_description struct {
Cooldown string
Cost string
Description string
Menu_items struct {
Description string
Value string
}
Rank_items struct {
Description string
Value string
}
Secondary_description string
}
}
Ability_description5 struct {
Item_description struct {
Cooldown string
Cost string
Description string
Menu_items struct {
Description string
Value string
}
Rank_items struct {
Description string
Value string
}
Secondary_description string
}
}
Basic_attack struct {
Item_description struct {
cooldown string
cost string
description string
Menu_items struct {
Description string
Value string
}
Rank_items struct {
Description string
Value string
}
Secondary_description string
}
}
Id int
Ret_msg string
}
这是我如何将JSON响应解组为结构体数组的方法:
var gods []God
json.Unmarshal(jsonResponse, &gods)
return gods
除了abilityDescription1(2,3,4,5)
和该结构体内的所有内容外,其他都可以正确解组。有什么建议吗?
英文:
Here's the sample JSON returning from the web API I'm invoking:
{
"Ability1": "Noxious Fumes",
"AbilityId1": 7812,
"AttackSpeed": 0.86,
"Cons": "",
"HP5PerLevel": 0.47,
"Health": 360,
"Speed": 350,
"abilityDescription1": {
"itemDescription": {
"cooldown": "12s",
"cost": "60/70/80/90/100",
"description": "Agni summons a cloud of noxious fumes at his ground target location, doing damage every second. Firing any of Agni's abilities into the fumes detonates the gas, stunning all enemies in the radius.",
"menuitems": [
{
"description": "Ability:",
"value": "Ground Target"
},
{
"description": "Affects:",
"value": "Enemy"
},
{
"description": "Damage:",
"value": "Magical"
},
{
"description": "Radius:",
"value": "20"
}
],
"rankitems": [
{
"description": "Damage per Tick:",
"value": "10/20/30/40/50 (+5% of your magical power)"
},
{
"description": "Fumes Duration:",
"value": "10s"
},
{
"description": "Stun Duration:",
"value": "1s"
}
],
"secondaryDescription": ""
}
},
"abilityDescription5": {
"itemDescription": {
"cooldown": "",
"cost": "",
"description": "After hitting with 4 basic attacks, Agni will gain a buff. On the next cast of Flame Wave or Rain Fire, all enemies hit by those abilities will be additionally set ablaze, taking damage every .5s for 3s.",
"menuitems": [
{
"description": "Affects:",
"value": "Enemy"
},
{
"description": "Damage:",
"value": "Magical"
}
],
"rankitems": [
{
"description": "Damage per Tick:",
"value": "5 (+10% of your magical power)"
}
],
"secondaryDescription": ""
}
},
"basicAttack": {
"itemDescription": {
"cooldown": "",
"cost": "",
"description": "",
"menuitems": [
{
"description": "Damage:",
"value": "34 + 1.5/Lvl (+20% of Magical Power)"
},
{
"description": "Progression:",
"value": "None"
}
],
"rankitems": [],
"secondaryDescription": ""
}
},
"id": 1737,
"ret_msg": null
}
And my struct:
type God struct {
Ability1 string
Ability2 string
Ability3 string
Ability4 string
Ability5 string
AbilityId1 int
AbilityId2 int
AbilityId3 int
AbilityId4 int
AbilityId5 int
Attack_speed float64
Attack_speed_per_level float64
Cons string
Hp5_per_level float64
Health int
Health_per_five int
Health_per_level int
Item1 string
Item2 string
Item3 string
Item4 string
Item5 string
Item6 string
Item7 string
Item8 string
Item9 string
ItemId1 int
ItemId2 int
ItemId3 int
ItemId4 int
ItemId5 int
ItemId6 int
ItemId7 int
ItemId8 int
ItemId9 int
Lore string
Mp5_per_level float64
Magic_protection int
Magic_protection_per_level int
Mana int
Mana_per_five float64
Mana_per_level int
Name string
On_free_rotation string
Pantheon string
Physical_power int
Physical_power_per_level int
Physical_protection int
Physical_protection_per_level float64
Pros string
Roles string
Speed int
Title string
Type string
Abilitydescription1 struct {
Item_description struct {
Cooldown string
Cost string
Description string
Menu_items struct {
Description string
Value string
}
Rank_items struct {
Description string
Value string
}
Secondary_description string
}
}
Ability_description2 struct {
Item_description struct {
Cooldown string
Cost string
Description string
Menu_items struct {
Description string
Value string
}
Rank_items struct {
Description string
Value string
}
Secondary_description string
}
}
Ability_description3 struct {
Item_description struct {
Cooldown string
Cost string
Description string
Menu_items struct {
Description string
Value string
}
Rank_items struct {
Description string
Value string
}
Secondary_description string
}
}
Ability_description4 struct {
Item_description struct {
Cooldown string
Cost string
Description string
Menu_items struct {
Description string
Value string
}
Rank_items struct {
Description string
Value string
}
Secondary_description string
}
}
Ability_description5 struct {
Item_description struct {
Cooldown string
Cost string
Description string
Menu_items struct {
Description string
Value string
}
Rank_items struct {
Description string
Value string
}
Secondary_description string
}
}
Basic_attack struct {
Item_description struct {
cooldown string
cost string
description string
Menu_items struct {
Description string
Value string
}
Rank_items struct {
Description string
Value string
}
Secondary_description string
}
}
Id int
Ret_msg string
}
Here's how I unmarshal the JSON response into the struct array:
var gods []God
json.Unmarshal(jsonResponse, &gods)
return gods
Everything is marshalling properly except the abilityDescription1(2,3,4,5)
and everything within that struct.
Any suggestions?
答案1
得分: 1
使用结构标签将JSON字段名映射到结构字段名。
你的许多结构字段都是小写的,因此无法被编码/解码包(encoding/json package)访问或编组。请查看http://golang.org/pkg/reflect/#StructTag(JSON包将“Description”与“description”匹配,即小写已经匹配)。
为了提高可读性和添加标签的能力,最好将结构拆分为单独的项,然后进行嵌入。你有一些重复使用Rank_items
的情况,而你可以定义它一次,然后根据需要进行嵌入:
例如:
Basic_attack struct {
ItemDescription ItemDesc `json:"itemDescription"`
Menu []MenuItems `json:"menuitems"`
Rank []RankItems `json:"rankitems"`
}
ItemDesc struct {
Cooldown string `json:"cooldown"`
Cost string `json:"cost"`
Description string `json:"description"`
Menu []MenuItems `json:"menuitems"`
...
}
MenuItems struct {
Description string
Value string
}
RankItems struct {
Description string
Value string
}
英文:
Use struct tags to map JSON field names to struct field names.
Many of your struct fields are lowercase and therefore unexported, which means the encoding/json package cannot access/marshal into them. Take a look at http://golang.org/pkg/reflect/#StructTag (the JSON package will match "Description" with "description", though - i.e. lower-case is already a match)
You are also better off (for readability/ability to add tags) splitting your structs into separate items, and then embedding them. You have cases where you're repeating Rank_items
, whereas you could define it once and then embed it as needed:
e.g.
Basic_attack struct {
ItemDescription ItemDesc `json:"itemDescription"`
Menu []MenuItems `json:"menuitems"`
Rank []RankItems `json:"rankitems"`
}
ItemDesc struct {
Cooldown string `json:"cooldown"`
Cost string `json:"cost"`
Description string `json:"description"`
Menu []MenuItems `json:"menuitems"`
...
}
MenuItems struct {
Description string
Value string
}
RankItems struct {
Description string
Value string
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论