英文:
Is it possible to Unmarshall a JSON which has varying field?
问题
我正在尝试从《英雄联盟》的静态数据库中获取英雄信息。以下是给出的链接:
问题在于,我只能通过英雄名称进行请求,而所有的JSON响应只有一个字段不同,即“main”字段,即英雄名称。你可以在下面的示例中找到有问题的字段:
还有树形表示:
我的目标是通过已知英雄名称范围的迭代来获取所有英雄的信息。你可以查看代码。我只需要几个字段,但是每次新请求时,主标签都会有所不同。
func GetHeroInfo(heroName string) *LolHeroInfo {
getUrl := fmt.Sprintf("http://ddragon.leagueoflegends.com/cdn/12.2.1/data/en_US/champion/%s.json", heroName)
fmt.Println(getUrl)
resp, err := http.Get(getUrl)
if err != nil {
fmt.Println(err)
return nil
}
defer resp.Body.Close()
read, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
return nil
}
heroGoverted := LolHeroInfo{}
err = json.Unmarshal(read, &heroGoverted)
if err != nil {
fmt.Println("unmarshall failed:", err)
return nil
}
return &heroGoverted
}
LolHeroInfo结构体类型是从这个链接中生成的:mholt的JSON转结构体
你可以查看另一个英雄的JSON响应,例如:Annie的JSON响应
是否有办法为JSON字段创建一个通用的结构体字段/标签?我相信这将非常困难,因为encoding/json包需要检查该JSON中特定标签的字段,但也许你之前遇到过这种问题。为每个英雄创建单独的结构体是不可能的,所以如果找不到解决方案,我将放弃这个案例。
提前感谢你的帮助。
英文:
I am tring to get League of Legends champion informations from LOL static database. Link is given below.
The problem is that i can only make request by hero names and all JSON responses are different from each other by only one field which is a "main" field; hero name. You can find problematic field as highlighted below:
Also tree respresentation:
My goal is to get all hero informations with iteration by range of known hero names as slice. You can check the code. I need only a couple of fields but the main tag is varies with every new request.
func GetHeroInfo(heroName string) *LolHeroInfo {
getUrl := fmt.Sprintf("http://ddragon.leagueoflegends.com/cdn/12.2.1/data/en_US/champion/%s.json", heroName)
fmt.Println(getUrl)
resp, err := http.Get(getUrl)
if err != nil {
fmt.Println(err)
return nil
}
defer resp.Body.Close()
read, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
return nil
}
heroGoverted := LolHeroInfo{}
err = json.Unmarshal(read, &heroGoverted)
if err != nil {
fmt.Println("unmarshall failed:", err)
return nil
}
return &heroGoverted }
Struct type LolHeroInfo is structifyed from this link: mholt's JSON to struct
You can check JSON response for another hero eg: JSON response for Annie .
Is there any way to make an agnostic struct field/tag for a JSON field. I believe this will be very hard because encoding/json package needs to check for field for particular tag in that JSON but maybe you encountered this kind of problem before. Creating separate struct for each hero is impossible so i will drop this case if i can't find a solution.
Thanks in advance for help.
答案1
得分: 2
由于你知道只有一个未知键,你可以将其解码为map[string]LolHeroInfo
,然后执行以下操作:
heroGoverted := LolHeroInfo{}
for _, v := range decoded.Data {
heroGoverted = v
}
英文:
Since you know it's just a single unknown key, you could just decode into a map[string]LolHeroInfo
for the Data
field, then do
heroGoverted := LolHeroInfo{}
for _, v := range decoded.Data {
heroGoverted = v
}
答案2
得分: 0
为了解决问题,我使用了@dave的解决方案。
我将主结构分成了两个单独的结构。这样可以消除不同的JSON字段:
type LolHeroInfo struct {
Type string `json:"type"`
Format string `json:"format"`
Version string `json:"version"`
Data map[string]HeroInfoStruct `json:"data"`
}
heroInfo := lib.GetHeroInfo(lolHeroes[i])
for _, v := range heroInfo.Data { //解组到第一个结构
a := lib.HeroInfoStruct{} //数据字段;第二个结构
a = v
fmt.Println(a.Lore) //现在我可以访问我需要的每个字段
}
英文:
To solve problem, I used @dave 's solution.
I breake main struct into two separate struct. This way varying JSON field eliminated:
type LolHeroInfo struct {
Type string `json:"type"`
Format string `json:"format"`
Version string `json:"version"`
Data map[string]HeroInfoStruct `json:"data"`
}
heroInfo := lib.GetHeroInfo(lolHeroes[i])
for _, v := range heroInfo.Data { //unmarshalled to first struct
a := lib.HeroInfoStruct{} //data field; second struct
a = v
fmt.Println(a.Lore)// now i can reach to every field that i need
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论