Ошибка при создании JSON вывода с ключом: значение в качестве имени тега с использованием структуры - PullRequest
0 голосов
/ 07 апреля 2020

Я хотел бы создать вывод JSON, как показано ниже,

{
   "Name": "John Smith",
   "City": "London",
   "Contact": [
     { "key": "StreetName", "value": "SomeName" },
     { "key": "PostalCode", "value": "SomeValue" }
   ],
}

Я пытаюсь добиться этого, используя код ниже,

package main

import (
        "encoding/json"
        "fmt"
        "log"
)

type Person struct {
   Name, City string
   Contact ContactStruct   
}

type ContactStruct struct {
   Street, PostalCode map[string]string
}

func main() {
  StreetData := make(map[string]string)
  StreetData["key"] = "StreetName"
  StreetData["value"] = "ABC Street"

  PostalCodeData := make(map[string]string)
  PostalCodeData["key"] = "PostalCode"
  PostalCodeData["value"] = "12345"

  jsonData := Person{
    Name: "John Smith",
    City: "London",
    Contact: ContactStruct{
       StreetData,
       PostalCodeData,
    },
  }

  finalJsonData, err := json.MarshalIndent(jsonData, " ", "   ")
  if err != nil {
    log.Fatal(err)
  }

  fmt.Println(string(finalJsonData))
}

Ниже приведен выходные данные генерируются с использованием приведенного выше кода,

 {
    "Name": "John Smith",
    "City": "London",
    "Contact": {
       "Street": {
          "key": "StreetName",
          "value": "ABC Street"
       },
       "PostalCode": {
          "key": "PostalCode",
          "value": "12345"
       }
    }
 }

Проблема: Как мы видим, выходные данные создаются с именами тегов "Street" и PostalCode , потому что мы создаем JSON с использованием значения struct.

Я пытался изучить различные варианты использования map[string]string и map[string]interface{} внутри Person struct. Но это не работает.

Есть ли какая-нибудь лучшая реализация, чтобы получить вывод JSON, согласно моему требованию, показанному в начале вопроса.

Заранее спасибо за помощь , Я недавно начал разработку в golang.

Работающий источник доступен здесь: https://play.golang.org/p/eIxDyWXfZ1C

Ответы [ 3 ]

2 голосов
/ 07 апреля 2020

Может быть, вы хотите это так


type Person struct {
    Name, City string
    Contact    []ContactStruct
}

type ContactStruct struct {
    Key   string
    Value string
}

func main() {

    StreetData := ContactStruct{Key: "StreetName", Value: "ABC Street"}
    PostalCodeData := ContactStruct{Key: "PostalCode", Value: "12345"}
    jsonData := Person{
        Name:    "John Smith",
        City:    "London",
        Contact: []ContactStruct{StreetData, PostalCodeData},
    }
    finalJsonData, err := json.MarshalIndent(jsonData, " ", "   ")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(string(finalJsonData))
}

0 голосов
/ 08 апреля 2020

Вы можете использовать пользовательский маршалер JSON для ContactStruct. Это позволяет по-прежнему использовать чистый тип данных Go, но при этом реализовать определенную сериализацию c, ожидаемую для связи с внешним миром.

Просмотр и запуск на Go детская площадка :

package main

import (
        "encoding/json"
        "fmt"
        "log"
)

type Person struct {
   Name, City string
   Contact ContactStruct   
}

type ContactStruct struct {
   Street, PostalCode string
}

func appendKV(buf []byte, key string, value string) ([]byte) {
    buf = append(buf, []byte(`{"key":`)...)
    b, _ := json.Marshal(key)
    buf = append(buf, b...)
    buf = append(buf, []byte(`,"value":`)...)
    b, _ = json.Marshal(value)
    buf = append(buf, b...)
    buf = append(buf, '}')
    return buf
}

func (cs ContactStruct) MarshalJSON() ([]byte, error) {
    buf := []byte{'['}
    buf = appendKV(buf, "StreetName", cs.Street)
    buf = append(buf, ',')
    buf = appendKV(buf, "PostalCode", cs.PostalCode)
    buf = append(buf, ']')
    return buf, nil
}


func main() {
  jsonData := Person{
    Name: "John Smith",
    City: "London",
    Contact: ContactStruct{
       Street: "ABC Street",
       PostalCode: "12345",
    },
  }

  finalJsonData, err := json.MarshalIndent(jsonData, " ", "   ")
  if err != nil {
    log.Fatal(err)
  }

  fmt.Println(string(finalJsonData))
}
0 голосов
/ 07 апреля 2020

Ваша структура довольно странная, но это решение: https://play.golang.org/p/CCVuiGd5phq

Быстрый совет: https://mholt.github.io/json-to-go/ используйте эту страницу, когда вам нужно структура для вашего json.

...