可以解析具有不同字段的 JSON 吗?

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

Is it possible to Unmarshall a JSON which has varying field?

问题

我正在尝试从《英雄联盟》的静态数据库中获取英雄信息。以下是给出的链接:

获取特定英雄的信息

问题在于,我只能通过英雄名称进行请求,而所有的JSON响应只有一个字段不同,即“main”字段,即英雄名称。你可以在下面的示例中找到有问题的字段:

可以解析具有不同字段的 JSON 吗?

还有树形表示:

可以解析具有不同字段的 JSON 吗?

我的目标是通过已知英雄名称范围的迭代来获取所有英雄的信息。你可以查看代码。我只需要几个字段,但是每次新请求时,主标签都会有所不同。

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.

Get info for specific hero

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:
可以解析具有不同字段的 JSON 吗?

Also tree respresentation:

可以解析具有不同字段的 JSON 吗?

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"`
}

可以解析具有不同字段的 JSON 吗?

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"`

}

可以解析具有不同字段的 JSON 吗?

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
	}

huangapple
  • 本文由 发表于 2022年2月1日 05:55:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/70933269.html
匿名

发表评论

匿名网友

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

确定