英文:
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
   }
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论