Как разобрать файл JSON с неизвестной структурой Golang - PullRequest
0 голосов
/ 01 января 2019

Я пытаюсь проанализировать и получить выбранные данные из глубоко вложенных данных JSON в Go Lang.У меня проблемы с навигацией по структуре и доступом к данным.Данные слишком глубоки и сложны, чтобы их можно было проанализировать априори известными структурами в Go.Вот URL-адрес файла: - 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 более низкого уровня?Можно ли рекурсивно разархивировать данные?

1 Ответ

0 голосов
/ 01 января 2019

Когда у вас есть данные как 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"`
}
...