doww38701 2019-01-01 17:04
浏览 166

如何解析结构未知的嵌套json文件Golang

I am trying to parse and get selected data from a deep nested json data in Go Lang. I'm having issues navigating through the structure and accessing the data. The data is too deep and complex to be parsed with a-priori known structures in Go. Here is the URL of the file: -https://www.data.gouv.fr/api/1/datasets/?format=csv&page=0&page_size=20

I did some parsing with map interfaces and using a json string:

resultdata := map[string]interface {}

json.Unmarshal([]byte(inputbytestring), &resultdata) //Inputstring is the string containing the JSON data of the above URL

The problem:

  • How can turn resultdata into a map (of strings), so I can use methods available for maps?
  • The JSON data is nested and has several levels. How is it possible to access the lower level JSON fields? is it possible to unmarshal the data recursively?
  • 写回答

1条回答 默认 最新

  • dtdr84101 2019-01-01 19:01
    关注

    Once you have data as a map[string]interface{}, you can use type assertions to get to the lower levels of data.

    There's a good explanation here of how to do this at https://blog.golang.org/json-and-go

    Here's an example to get you most of the way:

    https://play.golang.org/p/P8cGP1mTDmD

    package main

    import (
        "encoding/json"
        "fmt"
        "log"
    )
    
    func main() {
        jsonData := `{
        "string": "string_value",
        "number": 123.45,
        "js_array": ["a", "b", "c"],
        "integer": 678,
        "subtype": {
            "number_array": [1, 2, 3]
          }
        }`
    
        m := map[string]interface{}{}
        err := json.Unmarshal([]byte(jsonData), &m)
        if err != nil {
            log.Fatal(err)
        }
    
        for key, value := range m {
            switch v := value.(type) {
            case int:
                fmt.Printf("Key: %s, Integer: %d
    ", key, v)
            case float64:
                fmt.Printf("Key: %s, Float: %v
    ", key, v)
            case string:
                fmt.Printf("Key: %s, String: %s
    ", key, v)
            case map[string]interface{}:
                fmt.Printf("Key: %s, Subtype: %+v
    ", key, v)
            case []interface{}:
                //TODO: Read through each item in the interface and work out what type it is.
                fmt.Printf("Key: %s, []interface: %v
    ", key, v)
            default:
                fmt.Printf("Key: %s, unhandled type: %+v
    ", key, v)
            }
        }
    }
    

    Alternatively https://mholt.github.io/json-to-go/ does a decent job of turning examples of JSON data into Go structs that can be used for marshalling.

    Putting the example in, I get something that isn't too bad.

    type AutoGenerated struct {
        Data []struct {
            Acronym     interface{}   `json:"acronym"`
            Badges      []interface{} `json:"badges"`
            CreatedAt   string        `json:"created_at"`
            Deleted     interface{}   `json:"deleted"`
            Description string        `json:"description"`
            Extras      struct {
            } `json:"extras"`
            Frequency     string      `json:"frequency"`
            FrequencyDate interface{} `json:"frequency_date"`
            ID            string      `json:"id"`
            LastModified  string      `json:"last_modified"`
            LastUpdate    string      `json:"last_update"`
            License       string      `json:"license"`
            Metrics       struct {
                Discussions    int `json:"discussions"`
                Followers      int `json:"followers"`
                Issues         int `json:"issues"`
                NbHits         int `json:"nb_hits"`
                NbUniqVisitors int `json:"nb_uniq_visitors"`
                NbVisits       int `json:"nb_visits"`
                Reuses         int `json:"reuses"`
                Views          int `json:"views"`
            } `json:"metrics"`
            Organization struct {
                Acronym       string `json:"acronym"`
                Class         string `json:"class"`
                ID            string `json:"id"`
                Logo          string `json:"logo"`
                LogoThumbnail string `json:"logo_thumbnail"`
                Name          string `json:"name"`
                Page          string `json:"page"`
                Slug          string `json:"slug"`
                URI           string `json:"uri"`
            } `json:"organization"`
            Owner     interface{} `json:"owner"`
            Page      string      `json:"page"`
            Private   bool        `json:"private"`
            Resources []struct {
                Checksum struct {
                    Type  string `json:"type"`
                    Value string `json:"value"`
                } `json:"checksum"`
                CreatedAt   string      `json:"created_at"`
                Description interface{} `json:"description"`
                Extras      struct {
                } `json:"extras"`
                Filesize     int    `json:"filesize"`
                Filetype     string `json:"filetype"`
                Format       string `json:"format"`
                ID           string `json:"id"`
                LastModified string `json:"last_modified"`
                Latest       string `json:"latest"`
                Metrics      struct {
                    NbHits         int `json:"nb_hits"`
                    NbUniqVisitors int `json:"nb_uniq_visitors"`
                    NbVisits       int `json:"nb_visits"`
                    Views          int `json:"views"`
                } `json:"metrics"`
                Mime       string `json:"mime"`
                PreviewURL string `json:"preview_url"`
                Published  string `json:"published"`
                Title      string `json:"title"`
                Type       string `json:"type"`
                URL        string `json:"url"`
            } `json:"resources"`
            Slug             string        `json:"slug"`
            Spatial          interface{}   `json:"spatial"`
            Tags             []interface{} `json:"tags"`
            TemporalCoverage interface{}   `json:"temporal_coverage"`
            Title            string        `json:"title"`
            URI              string        `json:"uri"`
        } `json:"data"`
        Facets struct {
            Format [][]interface{} `json:"format"`
        } `json:"facets"`
        NextPage     string      `json:"next_page"`
        Page         int         `json:"page"`
        PageSize     int         `json:"page_size"`
        PreviousPage interface{} `json:"previous_page"`
        Total        int         `json:"total"`
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘