Maison > Article > développement back-end > Annuler le marshal des clés JSON contenant des guillemets simples
L'éditeur php Shinichi a introduit une technique intéressante, qui consiste à supprimer le marshal des clés JSON contenant des guillemets simples. Cette astuce peut aider les développeurs à être plus flexibles lors du traitement des données JSON et à éviter les erreurs d'analyse causées par l'inclusion de guillemets simples. En utilisant quelques astuces et fonctions simples, les développeurs peuvent facilement gérer cette situation et garantir une analyse et un traitement corrects des données JSON. Cette technique est très utile pour les développeurs qui traitent souvent des données JSON et peut améliorer l'efficacité du développement et la qualité du code.
Je suis très confus à ce sujet. J'ai besoin de charger des données sérialisées en json (à partir d'une base de données française) où certaines clés ont des guillemets simples.
Ceci est une version simplifiée :
package main import ( "encoding/json" "fmt" ) type product struct { name string `json:"nom"` cost int64 `json:"prix d'achat"` } func main() { var p product err := json.unmarshal([]byte(`{"nom":"savon", "prix d'achat": 170}`), &p) fmt.printf("product cost: %d\nerror: %s\n", p.cost, err) } // product cost: 0 // error: %!s(<nil>)
Unmarshalling ne provoque pas d'erreur, mais le "prix d'achat" (p.cost
) n'est pas analysé correctement.
Quand je désélectionne map[string]any
la touche "prix d'achat" s'analyse comme je l'attends :
package main import ( "encoding/json" "fmt" ) func main() { blob := map[string]any{} err := json.Unmarshal([]byte(`{"nom":"savon", "prix d'achat": 170}`), &blob) fmt.Printf("blob: %f\nerror: %s\n", blob["prix d'achat"], err) } // blob: 170.000000 // error: %!s(<nil>)
J'ai vérifié la json.marshal
documentation sur le balisage des structures mais je n'ai trouvé aucun problème avec les données que j'essaie de traiter.
Est-ce que j'ai raté quelque chose d'évident ici ? Comment analyser les clés json contenant des guillemets simples à l'aide de balises struct ?
Merci beaucoup pour vos idées !
Je n'ai rien trouvé dans la documentation, mais l'encodeur json traite les guillemets simples comme des caractères réservés dans les noms de balises.
func isvalidtag(s string) bool { if s == "" { return false } for _, c := range s { switch { case strings.containsrune("!#$%&()*+-./:;<=>?@[]^_{|}~ ", c): // backslash and quote chars are reserved, but // otherwise any punctuation chars are allowed // in a tag name. case !unicode.isletter(c) && !unicode.isdigit(c): return false } } return true }
Je pense qu'il est raisonnable de poser la question ici. En attendant, vous devrez implémenter json.unmarshaler et/ou json.marshaler. C'est un début :
func (p *Product) UnmarshalJSON(b []byte) error { type product Product // revent recursion var _p product if err := json.Unmarshal(b, &_p); err != nil { return err } *p = Product(_p) return unmarshalFieldsWithSingleQuotes(p, b) } func unmarshalFieldsWithSingleQuotes(dest interface{}, b []byte) error { // Look through the JSON tags. If there is one containing single quotes, // unmarshal b again, into a map this time. Then unmarshal the value // at the map key corresponding to the tag, if any. var m map[string]json.RawMessage t := reflect.TypeOf(dest).Elem() v := reflect.ValueOf(dest).Elem() for i := 0; i < t.NumField(); i++ { tag := t.Field(i).Tag.Get("json") if !strings.Contains(tag, "'") { continue } if m == nil { if err := json.Unmarshal(b, &m); err != nil { return err } } if j, ok := m[tag]; ok { if err := json.Unmarshal(j, v.Field(i).Addr().Interface()); err != nil { return err } } } return nil }
Essayez-le sur l'aire de jeux : https://www.php.cn/link/9b47b8678d84ea8a0f9fe6c4ec599918一个>
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!