Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk menyahmarshal json ke dalam struct tanpa memetakan semua elemen sambil mengekalkan semua maklumat

Bagaimana untuk menyahmarshal json ke dalam struct tanpa memetakan semua elemen sambil mengekalkan semua maklumat

王林
王林ke hadapan
2024-02-05 21:36:04417semak imbas

如何将 json 解组为结构体而不映射所有元素,同时保留所有信息

Kandungan soalan

Saya menerima objek JSON daripada baris gilir. Saya mahu memproses sebahagian daripada objek dan mengemas kininya sebelum menghantar ke baris gilir lain.

Jika saya ada input

{
  "one": "data1",
  "two": "data2",
  "three": "data3",
  ...
}

Saya ingin mengambil onetwo dan mengira beberapa maklumat sebelum menambah output baharu dan menghantar mesej yang serupa

{
  "one": "data1UPDATED",
  "two": "data2",
  "three": "data3",
  ...
  "extra_info": "extra"
}

Untuk dapat memproses data dengan lebih baik, saya ingin membongkar JSON ke dalam struktur yang serupa

type Message struct {
 One string `json:one`
 Two string `json:two`
}

Tetapi tidak mahu memetakan semua medan kerana kebanyakannya tidak berkaitan dengan aplikasi ini dan yang lain mungkin berubah.

Perkara yang saya telah cuba

Saya cuba memetakan semua medan ke json.RawMessage

type Message struct {
 One string `json:"one"`
 Two string `json:"two"`
 ExtraFields json.RawMessage `json:"-"`
}

Namun, semasa menyusun struktur, medan yang terkandung dalam ExtraFields tidak disertakan.

{
  "one": "data1",
  "two": "data2"
}

Saya juga cuba menulis unmarshalling tersuai yang menyimpan mesej lengkap dalam struktur, dengan mesej berguna dalam satu elemen dan maklumat lain dalam medan lain

type TmpMessage struct{
  Msg Message
  Others json.RawMessage
}

Tetapi ini menjadi sangat mengelirukan dan saya mengharapkan penyelesaian yang lebih bersih.

Adakah terdapat cara untuk melakukan ini, secara alternatif tanpa unmarshaller ke dalam struct dan hanya menggunakan yang asal map[string] 接口{}的唯一选择?


Jawapan betul


Anda boleh menulis unmarshaller tersuai seperti:

https://www.php.cn/link/a73d9b34d6f7c322fa3e34c633b1297d

func (m *Message) UnmarshalJSON(data []byte) error {
  tmp := make(map[string]interface{})
  if err := json.Unmarshal(data, &tmp); err != nil {
    return err
  }
  t := reflect.TypeOf(*m)
  for i := 0; i < t.NumField(); i++ {
    f := t.Field(i)
    if f.Name != "ExtraFields" {
      jsonTag := f.Tag.Get("json")
      // this part should probably by a type switch...
      reflect.ValueOf(m).Elem().Field(i).SetString(tmp[jsonTag].(string))
      delete(tmp, jsonTag)
    }
  }
  var err error
  m.ExtraFields, err = json.Marshal(tmp)
  return err
}

Atas ialah kandungan terperinci Bagaimana untuk menyahmarshal json ke dalam struct tanpa memetakan semua elemen sambil mengekalkan semua maklumat. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam