【问题标题】:How to parse a nest json file with unknown structure Golang如何解析具有未知结构Golang的嵌套json文件
【发布时间】:2019-05-28 13:39:41
【问题描述】:

我正在尝试从 Go Lang 中的深层嵌套 json 数据中解析和获取选定的数据。我在浏览结构和访问数据时遇到问题。数据太深太复杂,无法用 Go 中的先验已知结构进行解析。 这是文件的网址: -https://www.data.gouv.fr/api/1/datasets/?format=csv&page=0&page_size=20

我对地图接口做了一些解析,并使用了一个 json 字符串:

resultdata := map[string]interface {}

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

问题:

  • 如何将结果数据转换为(字符串)映射,以便我可以使用可用于映射的方法?
  • JSON 数据是嵌套的并且有多个级别。如何访问较低级别的 JSON 字段?是否可以递归解组数据?

【问题讨论】:

  • 正如@a-h 所说,JSON 的结构不是很糟糕,可以组成一个对应的 Go 结构。如果情况并非如此,并且您只能依赖字段名称和类型,那么我建议解析此类 JSON token by token

标签: json dictionary go interface nested


【解决方案1】:

如果您想对嵌套数据进行内联解码以便快速使用,请遵循以下方法:

myJsonData := `{
    "code": "string_code",
    "data": {
        "id": 123,
        "user": {
            "username": "my_username",
            "age": 30,
            "posts": [ "post1", "post2"]
        }
      }
    }`

假设您有上面嵌套的未知JSON数据要读取和解析,首先将其读入map[string]interface{}

m := map[string]interface{}{}
    err := json.Unmarshal([]byte(myJsonData), &m)
    if err != nil {
        log.Fatal(err)
    }

现在如果你想访问code

    fmt.Println(m["code"])

对于嵌套的data JSON 块中的id

    fmt.Println(m["data"].(map[string]interface{})["id"].(float64))

对于second level 嵌套的user JSON 块中的username

    fmt.Println(m["data"].(map[string]interface{})["user"].(map[string]interface{})["username"].(string))

对于second level 嵌套的user JSON 块中的age

    fmt.Println(m["data"].(map[string]interface{})["user"].(map[string]interface{})["age"].(float64))

对于third level 嵌套的posts JSON 块中的post1

    fmt.Println(m["data"].(map[string]interface{})["user"].(map[string]interface{})["posts"].([]interface{})[0].(string))

请查看playground中的示例

【讨论】:

  • 这个答案真的很有帮助,非常感谢!
【解决方案2】:

将数据作为map[string]interface{} 后,您可以使用类型断言来获取较低级别的数据。

https://blog.golang.org/json-and-go 有一个很好的解释说明如何做到这一点

这里有一个例子可以帮助你了解大部分情况:

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

主包

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\n", key, v)
        case float64:
            fmt.Printf("Key: %s, Float: %v\n", key, v)
        case string:
            fmt.Printf("Key: %s, String: %s\n", key, v)
        case map[string]interface{}:
            fmt.Printf("Key: %s, Subtype: %+v\n", 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\n", key, v)
        default:
            fmt.Printf("Key: %s, unhandled type: %+v\n", key, v)
        }
    }
}

或者,https://mholt.github.io/json-to-go/ 在将 JSON 数据示例转换为可用于编组的 Go 结构方面做得不错。

把例子放进去,我得到的东西还不错。

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

【讨论】:

    猜你喜欢
    • 2016-12-27
    • 2015-01-18
    • 1970-01-01
    • 2015-01-15
    • 1970-01-01
    • 2013-10-21
    • 2018-04-10
    • 2017-03-18
    • 1970-01-01
    相关资源
    最近更新 更多