Maison >développement back-end >Golang >Comment désorganiser les données JSON imbriquées sans connaître leur structure ?

Comment désorganiser les données JSON imbriquées sans connaître leur structure ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-02 22:15:29724parcourir

How to Unmarshal Nested JSON Data Without Knowing Its Structure?

Désagrégation du JSON imbriqué sans connaissances structurelles

Énoncé du problème

Lors du traitement des données JSON imbriquées , il peut être difficile de déterminer la structure appropriée dans laquelle procéder au désagrégation. Cela est particulièrement vrai pour les données stockées dans un magasin clé-valeur, où la structure des données JSON peut varier considérablement.

Question 1 : Éviter les démarshalings répétés

Alors un démarshalage répété peut entraîner une surcharge de performances, ce n'est pas nécessairement quelque chose à éviter à moins qu'il ne devienne un goulot d'étranglement important.

Question 2 : Détermination du type de structure

Il y en a deux principales méthodes pour déterminer le type de structure :

Méthode 1 : Démarshaling vers une interface

  1. Désassembler le json.RawMessage vers une map[string]interface{} en utilisant json.Unmarshal(*objmap["foo"], &myMap).
  2. Vérifiez le type des données JSON imbriquées dans myMap. Il révélera le type réel des données (par exemple, Baz, Bar).

Méthode 2 : Utiliser des expressions régulières

  1. Créer un fichier régulier expression pour extraire le champ de type des données JSON imbriquées.
  2. Utilisez la fonction regexp.FindString pour extraire le type.

Une fois le type de structure déterminé, vous pouvez ensuite annuler le marshalage du type. données :

varbazorbar interface{}
if err := json.Unmarshal(*objmap["foo"], &bazorbar); err !=nil{
   return err
}

switch v := bazorbar.(type) {
case map[string]*json.RawMessage:
   // If the data is a nested JSON object, further unmarshaling is needed.
   result, err := unmarshalNested(v["nested_data"])
   if err != nil
      return err
   foo.Nested_Data = result
case []interface{}:
   // If the data is an array of JSON objects, process each element.
   for _, item := range v {
      result, err := unmarshalNested(item.(map[string]interface{}))
      if err != nil
         return err
      foo.Nested_Array = append(foo.Nested_Array, result)
   }
}

Exemple de code :

// Unmarshals nested JSON data.
func unmarshalNested(data map[string]interface{}) (interface{}, error) {
   type_expr := regexp.MustCompile(`"type":\s*"([a-zA-Z]+)"`)
   matches := type_expr.FindStringSubmatch(data["foo"].(string))

   if len(matches) == 2 {
      switch matches[1] {
         case "Baz":
            var baz Baz
            if err := json.Unmarshal([]byte(data["foo"].(string)), &baz); err != nil {
               return nil, err
            }
            return baz, nil
         case "Bar":
            var bar Bar
            if err := json.Unmarshal([]byte(data["foo"].(string)), &bar); err != nil {
               return nil, err
            }
            return bar, nil
      }
   }
   return nil, errors.New("cannot determine type")
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn