【问题标题】:Unmarshalling Complex Json解组复杂 Json
【发布时间】:2017-02-19 16:58:00
【问题描述】:

我最近才开始使用 api 和 http 请求,我正在尝试构建一个使用 Reddit API 来拉取特定 subreddit 上的帖子的应用程序。

这是我正在练习的带有 json 和搜索参数的页面: https://www.reddit.com/r/hiphopheads.json?limit=1

看Golang的JSON模块的标准库,还是不明白怎么用json.Unmarshal来处理这个复杂的JSON。根据我的收集,我必须定义一个类似于 JSON 结构的结构来实际保存数据

我将链接发布到此网站以了解 JSON 的实际结构:https://jsonformatter.curiousconcept.com/

现在我主要关注的是 Data->Children->Data->Title 下的标题。如果我想将 JSON 解组为一个对象,是否定义一个嵌套结构对象?或者有没有更简单的方法来做到这一点,这样我就不必弄清楚 JSON 的所有属性并自己定义它们??

非常感谢任何能让我走上正轨的帮助。谢谢!

【问题讨论】:

    标签: json go reddit


    【解决方案1】:

    您不必在结构中定义不需要的字段。 Unmarshal 只会解码结构中存在的值。但不幸的是,对于嵌套的 JSON,您还必须定义所有父字段(与 xml 包不同,您可以在标签中定义路径)。所以你的结构可能看起来像这样:

    type Foo struct {
        Data struct {
            Children []struct {
                Data struct {
                    Title string
                }
            }
        }
    }
    

    查看这里的工作示例:https://play.golang.org/p/UeUYfWBONL

    【讨论】:

    • 感谢您的回答,非常简单明了。我对 XML 也不太了解,但我想我会看看它,看看它与 JSON 有何不同。
    • 不同之处在于,在 xml 包中,如果要解码嵌套值,可以将路径放在标签中,如下所示:type Foo struct { Title string 'xml:"data>children>data>title"'} 不知道为什么在 json 包中不可能,因为它真的很方便,不得不只定义一个结构(在这种情况下不是 4 个)。不然包真的很像
    【解决方案2】:

    您尝试解组的 JSON 似乎过于复杂,因此您的结构必须很复杂,但这就是它的方式。

    有一些工具可以从 JSON 生成结构定义,这可以节省大量工作。使用您发布的 JSON 和 such an online tool,我生成了以下结构:

    package main
    
    type MyJsonName struct {
        Data struct {
            After    string      `json:"after"`
            Before   interface{} `json:"before"`
            Children []struct {
                Data struct {
                    ApprovedBy          interface{}   `json:"approved_by"`
                    Archived            bool          `json:"archived"`
                    Author              string        `json:"author"`
                    AuthorFlairCSSClass string        `json:"author_flair_css_class"`
                    AuthorFlairText     interface{}   `json:"author_flair_text"`
                    BannedBy            interface{}   `json:"banned_by"`
                    Clicked             bool          `json:"clicked"`
                    ContestMode         bool          `json:"contest_mode"`
                    Created             int           `json:"created"`
                    CreatedUtc          int           `json:"created_utc"`
                    Distinguished       string        `json:"distinguished"`
                    Domain              string        `json:"domain"`
                    Downs               int           `json:"downs"`
                    Edited              bool          `json:"edited"`
                    Gilded              int           `json:"gilded"`
                    Hidden              bool          `json:"hidden"`
                    HideScore           bool          `json:"hide_score"`
                    ID                  string        `json:"id"`
                    IsSelf              bool          `json:"is_self"`
                    Likes               interface{}   `json:"likes"`
                    LinkFlairCSSClass   string        `json:"link_flair_css_class"`
                    LinkFlairText       string        `json:"link_flair_text"`
                    Locked              bool          `json:"locked"`
                    Media               interface{}   `json:"media"`
                    MediaEmbed          struct{}      `json:"media_embed"`
                    ModReports          []interface{} `json:"mod_reports"`
                    Name                string        `json:"name"`
                    NumComments         int           `json:"num_comments"`
                    NumReports          interface{}   `json:"num_reports"`
                    Over18              bool          `json:"over_18"`
                    Permalink           string        `json:"permalink"`
                    Quarantine          bool          `json:"quarantine"`
                    RemovalReason       interface{}   `json:"removal_reason"`
                    ReportReasons       interface{}   `json:"report_reasons"`
                    Saved               bool          `json:"saved"`
                    Score               int           `json:"score"`
                    SecureMedia         interface{}   `json:"secure_media"`
                    SecureMediaEmbed    struct{}      `json:"secure_media_embed"`
                    Selftext            string        `json:"selftext"`
                    SelftextHTML        string        `json:"selftext_html"`
                    Stickied            bool          `json:"stickied"`
                    Subreddit           string        `json:"subreddit"`
                    SubredditID         string        `json:"subreddit_id"`
                    SuggestedSort       interface{}   `json:"suggested_sort"`
                    Thumbnail           string        `json:"thumbnail"`
                    Title               string        `json:"title"`
                    Ups                 int           `json:"ups"`
                    URL                 string        `json:"url"`
                    UserReports         []interface{} `json:"user_reports"`
                    Visited             bool          `json:"visited"`
                } `json:"data"`
                Kind string `json:"kind"`
            } `json:"children"`
            Modhash string `json:"modhash"`
        } `json:"data"`
        Kind string `json:"kind"`
    }
    

    通常,这些工具的输出仍需要手动调整才能正常工作。例如:

    MediaEmbed          struct{}      `json:"media_embed"`
    

    我很确定这不是这里需要的。但它在展示基本思想和正确理解大部分内容方面确实有很长的路要走。您可以尝试其他类似的工具。

    【讨论】:

    • 感谢您的回答。该工具似乎非常有用,并且肯定会在将来使用 JSON 时有所帮助。再次感谢。
    猜你喜欢
    • 2020-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-21
    • 2020-10-29
    • 2021-06-20
    • 2018-01-05
    相关资源
    最近更新 更多