У меня есть данные JSON, которые выглядят так:

    [
      {
        lat: "41.189301799999996",
        lon: "11.918255998031015",
        display_name: "Some place",
        address: {
          address: "Address",
          country: "Country",
          country_code: "CC"
        },
        geojson: {
          type: "Polygon",
          coordinates: [
             [
               [14.4899021,41.4867039],
               [14.5899021,41.5867039],
             ]
          ]
        }
     }
   ]

Я хотел бы проанализировать эти данные, взять первый элемент из этого массива и преобразовать его в новую структуру, которая будет выглядеть следующим образом:

type Location struct {
    Name        string
    Country     string
    CountryCode string
    Center      Coordinate
    Coordinates []Coordinate
}

Я определил тип координат следующим образом:

type Coordinate struct {
    Lat string `json:"lat"`
    Lng string `json:"lon"`
}

Но, если попытаться разобрать это так:

bytes, err := ioutil.ReadAll(res.Body)

if err != nil {
    http.Error(w, err.Error(), http.StatusBadRequest)
}

var locations [0]Location

if err := json.Unmarshal(bytes, &locations); err != nil {
    fmt.Println("Error parsing json", err)
}

fmt.Println(locations)

Но это дает мне это в терминале:

[{   { } []}]

Как я могу разобрать такую структуру json и преобразовать ее в структуру location?

0
Leff 28 Апр 2020 в 01:06

2 ответа

Лучший ответ

Вы должны использовать структуру, которая соответствует входному документу, чтобы unmarshal:

type Entry struct {
  Lat string `json:"lat"`
  Lon string `json:"lon"`
  DisplayName string `json:"display_name"`
  Address struct {
      Address string `json:"address"`
      Country string `json:"country"`
      Code string `json:"country_code"`
  } `json:"address"`
  Geo struct {
     Type string `json:"type"`
     Coordinates [][][]float64 `json:"coordinates"`
  } `json:"geojson"`
}

Затем распакуйте в массив Entry:

var entries []Entry
json.Unmarshal(data,&entries)

И используйте entries для построения Location

1
Burak Serdar 27 Апр 2020 в 22:28

Вы должны быть более точными с вашей структурой, к которой вы Unmarshal. Вы также должны иметь двойные кавычки вокруг ваших ключей согласно официальной спецификации JSON. Пропускать кавычки можно только внутри JavaScript, JSON требует их.

И последнее, я знаю, что это глупо, но последняя запятая после последнего внутреннего массива также была недействительной, пришлось удалить это:

package main

import (
    "encoding/json"
    "fmt"
)

type Location struct {
    Lat         string     `json:"lat"`
    Lng         string     `json:"lon"`
    DisplayName string     `json:"display_name"`
    Address     Address    `json:"address"`
    GeoJSON     Geo        `json:"geojson"`
}

type Address struct {
    Address     string `json:"address"`
    Country     string `json:"country"`
    CountryCode string `json:"country_code"`
}

type Geo struct {
    Type        string         `json:"type"`
    Coordinates [][]Coordinate `json:"coordinates"`
}

type Coordinate [2]float64

func main() {
    inputJSON := `
    [
          {
            "lat": "41.189301799999996",
            "lon": "11.918255998031015",
            "display_name": "Some place",
            "address": {
              "address": "123 Main St.",
              "country": "USA",
              "country_code": "+1"
            },
            "geojson": {
              "type": "Polygon",
              "coordinates": [
                [
                  [14.4899021,41.4867039],
                  [14.5899021,41.5867039]
                ]
              ]
            }
          }
        ]`

    var locations []Location

    if err := json.Unmarshal([]byte(inputJSON), &locations); err != nil {
        panic(err)
    }

    fmt.Printf("%#v\n", locations)
}

Вы также можете запустить его на игровой площадке Go!

1
GoForth 27 Апр 2020 в 22:48