doudiza9154
doudiza9154
2017-08-19 17:28

在golang中解组深层嵌套的json

已采纳

I have an ugly way of unmarshalling the following json, but it requires much manual work. I am looking for a more programmatic way to obtain the various team names, if I didn't know how many teams exactly there were originally. It's truly one of the most poorly structured api's I've come across.

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

The following works, but it's a hassle and I have to hard code the different struct values per team, to get data for that team.

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)
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • duandazhen7306 duandazhen7306 4年前

    You probably want to use a custom JSON unmarshaller for this. You can see an example of how to use one here: http://choly.ca/post/go-json-marshalling/

    Since the data is structured the way it is, with the teams section both containing teams and the count field, you'll likely need a fair bit of manual logic in there.

    First, you can start by defining the 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:"-"`
    }
    

    Next, we can define the Team structure the way we want it to look.

    type Team struct {
        // Declare the fields of a Team
    }
    

    And finally, we declare a custom unmarshal function for the 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
    }
    

    The unmarshal function will be called by Golangs json library automatically when it hits the League structure inside the LeagueApiResult.

    点赞 评论 复制链接分享

为你推荐