在golang中解析深度嵌套的json

3

我有一种丑陋的方式来反序列化以下json,但它需要大量手动操作。 如果我不知道原始团队数量,我正在寻找一种更加程序化的方法来获取各个团队名称。 这确实是我遇到的最糟糕的API之一。

data := []byte(`{
    "fantasy_content": {
        "copyright": "Data provided by Yahoo! and STATS, LLC",
        "league": [
            {
                "allow_add_to_dl_extra_pos": 0,
                "current_week": "1",
                "draft_status": "predraft",
                "edit_key": "1",
                "end_date": "2017-12-25",
                "end_week": "16",
                "game_code": "nfl",
                "is_cash_league": "0",
                "is_pro_league": "0",
                "league_id": "XXXXX",
                "league_key": "XXXX",
                "league_type": "private",
                "league_update_timestamp": null,
                "name": "XXXXXX",
                "num_teams": 14,
                "renew": "XXXX",
                "renewed": "",
                "scoring_type": "head",
                "season": "2017",
                "short_invitation_url": "XXXXX",
                "start_date": "2017-09-07",
                "start_week": "1",
                "url": "XXXXXX",
                "weekly_deadline": ""
            },
            {
                "teams": {
                    "0": {
                        "team": [
                            [
                                {
                                    "team_key": "XXXX"
                                },
                                {
                                    "team_id": "1"
                                },
                                {
                                    "name": "XXXXX"
                                },
                                [],
                                {
                                    "url": "XXXXX"
                                },
                                {
                                    "team_logos": [
                                        {
                                            "team_logo": {
                                                "size": "large",
                                                "XXX"
                                            }
                                        }
                                    ]
                                },
                                [],
                                {
                                    "waiver_priority": ""
                                },
                                {
                                    "faab_balance": "100"
                                },
                                {
                                    "number_of_moves": 0
                                },
                                {
                                    "number_of_trades": 0
                                },
                                {
                                    "roster_adds": {
                                        "coverage_type": "week",
                                        "coverage_value": "1",
                                        "value": "0"
                                    }
                                },
                                [],
                                {
                                    "league_scoring_type": "head"
                                },
                                [],
                                [],
                                {
                                    "has_draft_grade": 0
                                },
                                [],
                                [],
                                {
                                    "managers": [
                                        {
                                            "manager": {
                                                "email": "XXXXX",
                                                "guid": "XX",
                                                "image_url": "https://s.yimg.com/wm/modern/images/default_user_profile_pic_64.png",
                                                "is_commissioner": "1",
                                                "manager_id": "1",
                                                "nickname": "Andrew"
                                            }
                                        }
                                    ]
                                }
                            ]
                        ]
                    },
                    "1": {
                        "team": [
                            [
                                {
                                    "team_key": "XXXXX"
                                },
                                {
                                    "team_id": "2"
                                },
                                {
                                    "name": "XXXXX"
                                },
                                [],
                                {
                                    "url": "XXXXX"
                                },
                                {
                                    "team_logos": [
                                        {
                                            "team_logo": {
                                                "size": "large",
                                                "url": "XXXX"
                                            }
                                        }
                                    ]
                                },
                                [],
                                {
                                    "waiver_priority": ""
                                },
                                {
                                    "faab_balance": "100"
                                },
                                {
                                    "number_of_moves": 0
                                },
                                {
                                    "number_of_trades": 0
                                },
                                {
                                    "roster_adds": {
                                        "coverage_type": "week",
                                        "coverage_value": "1",
                                        "value": "0"
                                    }
                                },
                                [],
                                {
                                    "league_scoring_type": "head"
                                },
                                [],
                                [],
                                {
                                    "has_draft_grade": 0
                                },
                                [],
                                [],
                                {
                                    "managers": [
                                        {
                                            "manager": {
                                                "email": "XXXX@yahoo.com",
                                                "guid": "XXXX",
                                                "image_url": "https://s.yimg.com/wm/modern/images/default_user_profile_pic_64.png",
                                                "manager_id": "2",
                                                "nickname": "Andrew"
                                            }
                                        },
                                        {
                                            "manager": {
                                                "email": "XXX@yahoo.com",
                                                "guid": "XX",
                                                "image_url": "https://s.yimg.com/wm/modern/images/default_user_profile_pic_64.png",
                                                "is_comanager": "1",
                                                "manager_id": "15",
                                                "nickname": "XX"
                                            }
                                        }
                                    ]
                                }
                            ]
                        ]
                    },
                    "10": {
                        "team": [
                            [
                                {
                                    "team_key": "XXX"
                                },
                                {
                                    "team_id": "11"
                                },
                                {
                                    "name": "XXX"
                                },
                                [],
                                {
                                    "url": "https://football.fantasysports.yahoo.com/f1/XXX"
                                },
                                {
                                    "team_logos": [
                                        {
                                            "team_logo": {
                                                "size": "large",
                                                "url": "https://s.yimg.com/dh/ap/fantasy/nfl/img/icon_01_100.png"
                                            }
                                        }
                                    ]
                                },
                                [],
                                {
                                    "waiver_priority": ""
                                },
                                {
                                    "faab_balance": "100"
                                },
                                {
                                    "number_of_moves": 0
                                },
                                {
                                    "number_of_trades": 0
                                },
                                {
                                    "roster_adds": {
                                        "coverage_type": "week",
                                        "coverage_value": "1",
                                        "value": "0"
                                    }
                                },
                                [],
                                {
                                    "league_scoring_type": "head"
                                },
                                [],
                                [],
                                {
                                    "has_draft_grade": 0
                                },
                                [],
                                [],
                                {
                                    "managers": [
                                        {
                                            "manager": {
                                                "email": "XXX@gmail.com",
                                                "guid": "XX",
                                                "image_url": "https://s.yimg.com/wm/modern/images/default_user_profile_pic_64.png",
                                                "manager_id": "11",
                                                "nickname": "XX"
                                            }
                                        }
                                    ]
                                }
                            ]
                        ]
                    },
                    "2": {
                        "team": [
                            [
                                {
                                    "team_key": "371.l.102542.t.3"
                                },
                                {
                                    "team_id": "3"
                                },
                                {
                                    "name": "XXX"
                                },
                                [],
                                {
                                    "url": "https://football.fantasysports.yahoo.com/f1/XX/3"
                                },
                                {
                                    "team_logos": [
                                        {
                                            "team_logo": {
                                                "size": "large",
                                                "url": "https://ct.yimg.com/cy/5603/30147468023_1c705edb29_192sq.jpg?ct=fantasy"
                                            }
                                        }
                                    ]
                                },
                                [],
                                {
                                    "waiver_priority": ""
                                },
                                {
                                    "faab_balance": "100"
                                },
                                {
                                    "number_of_moves": 0
                                },
                                {
                                    "number_of_trades": 0
                                },
                                {
                                    "roster_adds": {
                                        "coverage_type": "week",
                                        "coverage_value": "1",
                                        "value": "0"
                                    }
                                },
                                [],
                                {
                                    "league_scoring_type": "head"
                                },
                                [],
                                [],
                                {
                                    "has_draft_grade": 0
                                },
                                [],
                                [],
                                {
                                    "managers": [
                                        {
                                            "manager": {
                                                "email": "XXXgmail.com",
                                                "guid": "XXXX",
                                                "image_url": "https://s.yimg.com/wv/images/6c93ed606f742d4c075bc091633cc072_64.jpg",
                                                "manager_id": "3",
                                                "nickname": "XX"
                                            }
                                        }
                                    ]
                                }
                            ]
                        ]
                    },
                    "3": {
                        "team": [
                            [
                                {
                                    "team_key": "371.l.102542.t.4"
                                },
                                {
                                    "team_id": "4"
                                },
                                {
                                    "name": "XX"
                                },
                                [],
                                {
                                    "url": "https://football.fantasysports.yahoo.com/f1/XX/4"
                                },
                                {
                                    "team_logos": [
                                        {
                                            "team_logo": {
                                                "size": "large",
                                                "url": "https://s.yimg.com/dh/ap/fantasy/nfl/img/icon_10_100.png"
                                            }
                                        }
                                    ]
                                },
                                [],
                                {
                                    "waiver_priority": ""
                                },
                                {
                                    "faab_balance": "100"
                                },
                                {
                                    "number_of_moves": 0
                                },
                                {
                                    "number_of_trades": 0
                                },
                                {
                                    "roster_adds": {
                                        "coverage_type": "week",
                                        "coverage_value": "1",
                                        "value": "0"
                                    }
                                },
                                [],
                                {
                                    "league_scoring_type": "head"
                                },
                                [],
                                [],
                                {
                                    "has_draft_grade": 0
                                },
                                [],
                                [],
                                {
                                    "managers": [
                                        {
                                            "manager": {
                                                "email": "XXX@yahoo.com",
                                                "guid": "XX",
                                                "image_url": "https://s.yimg.com/wm/modern/images/default_user_profile_pic_64.png",
                                                "manager_id": "4",
                                                "nickname": "XX"
                                            }
                                        }
                                    ]
                                }
                            ]
                        ]
                    },
                    "8": {
                        "team": [
                            [
                                {
                                    "team_key": "XXX"
                                },
                                {
                                    "team_id": "9"
                                },
                                {
                                    "name": "XxX"
                                },
                                [],
                                {
                                    "url": "https://football.fantasysports.yahoo.com/f1/XX/9"
                                },
                                {
                                    "team_logos": [
                                        {
                                            "team_logo": {
                                                "size": "large",
                                                "url": "https://ct.yimg.com/cy/8393/28682944304_33bda49603_192sq.jpg?ct=fantasy"
                                            }
                                        }
                                    ]
                                },
                                [],
                                {
                                    "waiver_priority": ""
                                },
                                {
                                    "faab_balance": "100"
                                },
                                {
                                    "number_of_moves": 0
                                },
                                {
                                    "number_of_trades": 0
                                },
                                {
                                    "roster_adds": {
                                        "coverage_type": "week",
                                        "coverage_value": "1",
                                        "value": "0"
                                    }
                                },
                                [],
                                {
                                    "league_scoring_type": "head"
                                },
                                [],
                                [],
                                {
                                    "has_draft_grade": 0
                                },
                                [],
                                [],
                                {
                                    "managers": [
                                        {
                                            "manager": {
                                                "email": "XXX",
                                                "guid": "XXX",
                                                "image_url": "https://s.yimg.com/wm/modern/images/default_user_profile_pic_64.png",
                                                "manager_id": "9",
                                                "nickname": "XXX"
                                            }
                                        }
                                    ]
                                }
                            ]
                        ]
                    },
                    "count": 14
                }
            }
        ],
        "refresh_rate": "60",
        "time": "110.55207252502ms",
        "xml:lang": "en-US",
        "yahoo:uri": "/fantasy/v2/league/XXXX/teams"
    }
}`)

以下方式可以实现,但是很麻烦,我需要针对每个团队硬编码不同的结构值来获取该团队的数据。
type TeamApi_ struct {
    TeamKey string `json:"team_key"`
    TeamId string `json:"team_id"`
    Name string `json:"name"`
}

type LeaguesApi struct {
    NumTeams int `json:"num_teams"`
    TeamsApi struct {
        Zero struct {
            TeamsApi_ [][]TeamApi_ `json:"team"`
        } `json:"0"`
        One struct {
            TeamsApi_ [][]TeamApi_ `json:"team"`
        } `json:"1"`
        Two struct {
            TeamsApi_ [][]TeamApi_ `json:"team"`
        } `json:"2"`
        Three struct {
            TeamsApi_ [][]TeamApi_ `json:"team"`
        } `json:"3"`
    } `json:"teams"`
} 

type LeagueApiResult struct {
FantasyContent struct {
            LeagueApi []LeaguesApi `json:"league"`

    } `json:"fantasy_content"`
}

var Result LeagueApiResult
err := json.Unmarshal(data, &Result)
if err != nil {
    fmt.Println(err)
}


fmt.Println(Result.FantasyContent.LeagueApi[1].TeamsApi.One.TeamsApi_[0][2].Name)

2
如果需要解析第三方JSON,请使用生成器示例生成器 - R Menke
这很有用,但并不能完全帮助。我最终仍然得到TeamsApi结构体,其中每个元素都被命名为结构体(Zero、One、Two)。我需要以某种编程方式迭代TeamsApi结构体,以获取每个元素作为它们自己的变量。 - Ceej
1个回答

2
您可能需要使用自定义的JSON反序列化器来处理此内容。您可以在此处查看如何使用它的示例:http://choly.ca/post/go-json-marshalling/ 由于数据结构是这样的,即“teams”部分既包含团队又包含“count”字段,因此您可能需要进行相当多的手动逻辑处理。
首先,您可以开始定义“League”:
type League struct {
    AllowAddToDlExtraPos  int                    `json:"allow_add_to_dl_extra_pos,omitempty"`
    CurrentWeek           string                 `json:"current_week,omitempty"`
    DraftStatus           string                 `json:"draft_status,omitempty"`
    EditKey               string                 `json:"edit_key,omitempty"`
    EndDate               string                 `json:"end_date,omitempty"`
    EndWeek               string                 `json:"end_week,omitempty"`
    GameCode              string                 `json:"game_code,omitempty"`
    IsCashLeague          string                 `json:"is_cash_league,omitempty"`
    IsProLeague           string                 `json:"is_pro_league,omitempty"`
    LeagueID              string                 `json:"league_id,omitempty"`
    LeagueKey             string                 `json:"league_key,omitempty"`
    LeagueType            string                 `json:"league_type,omitempty"`
    LeagueUpdateTimestamp interface{}            `json:"league_update_timestamp,omitempty"`
    Name                  string                 `json:"name,omitempty"`
    NumTeams              int                    `json:"num_teams,omitempty"`
    Renew                 string                 `json:"renew,omitempty"`
    Renewed               string                 `json:"renewed,omitempty"`
    ScoringType           string                 `json:"scoring_type,omitempty"`
    Season                string                 `json:"season,omitempty"`
    ShortInvitationURL    string                 `json:"short_invitation_url,omitempty"`
    StartDate             string                 `json:"start_date,omitempty"`
    StartWeek             string                 `json:"start_week,omitempty"`
    URL                   string                 `json:"url,omitempty"`
    WeeklyDeadline        string                 `json:"weekly_deadline,omitempty"`
    Teams                 []Team                 `json:"-"`
}

接下来,我们可以按照自己的想法定义Team结构。
type Team struct {
    // Declare the fields of a Team
}

最后,我们为League声明一个自定义的反序列化函数。

func (l *League) UnmarshalJSON(data []byte) error {
    type Alias League
    aux := &struct {
        *Alias
        Teams map[string]interface{} `json:"teams"`
    }{
        Alias: (*Alias)(l),
    }

    if err := json.Unmarshal(data, aux); err != nil {
        return err
    }

    var teams []Team
    for num, team := range aux.Teams {
        // Add your code to parse each of the teams from the 
        // map you declared above.
    }
    l.Teams = teams

    return nil
}
unmarshal函数将在Golang的json库自动调用,当它遇到LeagueApiResult中的League结构时。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接