3 votes

Déchiffrer JSON en fonction de la clé

Je reçois des données formatées en JSON depuis le réseau, et j'ai besoin de les décompresser en fonction d'une clé.
Voici un exemple de données :

{
  "foo": {
    "11883920": {
      "fieldA": 123,
      "fieldB": [
        {
          "fieldC": "a",
          "fieldD": 1173653.22
        }
      ]
    }
  },
  "bar": {
     "123": {
       "fieldE": 123
     }
   }
  "anyOtherkey": {...}
}

La logique est la suivante : si la clé est foo il devrait être dépourvu de cachet comme fooStruct et si bar - en tant que barStruct . Quelle est la meilleure façon de mettre en œuvre cette logique ? (Je ne veux pas l'annuler pour l'appliquer à map[string]interface{} Il est peut-être possible de le faire avec json.NewDecoder() mais je n'ai pas obtenu le résultat escompté).

5voto

Elias Van Ootegem Points 29404

Il suffit de créer un type avec les deux champs présents :

type MyType struct {
    Foo      *fooStruct `json:"foo,omitempty"`
    Bar      *barStruct `json:"bar,omitempty"`
    OtherKey string     `json:"other_key"`
}

Déchiffrez le JSON dans ce type, et vérifiez simplement ig Foo et ou Bar ne sont pas nécessaires pour savoir avec quelles données vous travaillez.

Voici un terrain de jeu Démonstration de ce à quoi cela ressemblerait

L'essentiel est là :

type Foo struct {
    Field int `json:"field1"`
}

type Bar struct {
    Message string `json:"field2"`
}

type Payload struct {
    Foo   *Foo   `json:"foo,omitempty"`
    Bar   *Bar   `json:"bar,omitempty"`
    Other string `json:"another_field"`
}

Le Foo y Bar sont des types de pointeurs, car les champs de valeur rendraient un peu plus fastidieuse la détermination du champ réellement défini. Les omitempty permet de marshaller le même type pour recréer la charge utile d'origine, comme le fait nil n'apparaîtront pas dans le résultat.

Pour vérifier quel champ a été défini dans la chaîne JSON d'origine, il suffit d'écrire :

var data Payload
if err := json.Unmarshal([]byte(jsonString), &data); err != nil {
    // handle error
}
if data.Foo == nil && data.Bar == nil {
    // this is probably an error-case you need to handle
}
if data.Foo == nil {
    fmt.Println("Bar was set")
} else {
    fmt.Println("Foo was set")
}

Rien de plus

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X