Objets JSON nesteds sans désordre dans Golang

Il y a quelques questions sur le sujet mais aucune ne semble couvrir mon cas, donc je crée un nouveau.

J’ai JSON comme suit:

{"foo":{ "bar": "1", "baz": "2" }, "more": "text"} 

Existe-t-il un moyen de supprimer la propriété de la barre nestede et de l’affecter directement à une propriété struct sans créer de structure nestede?

La solution que j’adopte maintenant est la suivante:

 type Foo struct { More Ssortingng `json:"more"` Foo struct { Bar ssortingng `json:"bar"` Baz ssortingng `json:"baz"` } `json:"foo"` // FooBar ssortingng `json:"foo.bar"` } 

Ceci est une version simplifiée, veuillez ignorer la verbosité. Comme vous pouvez le voir, je voudrais pouvoir parsingr et atsortingbuer la valeur à

 // FooBar ssortingng `json:"foo.bar"` 

J’ai vu des gens utiliser une carte, mais ce n’est pas mon cas. En gros, je ne me soucie pas du contenu de foo (qui est un gros object), sauf pour quelques éléments spécifiques.

Quelle est l’approche correcte dans ce cas? Je ne cherche pas de piratage bizarre, donc si c’est la voie à suivre, ça me va.

Existe-t-il un moyen de supprimer la propriété de la barre nestede et de l’affecter directement à une propriété struct sans créer de structure nestede?

Non, l’encodage / json ne peut pas faire l’affaire avec “> un peu> deep> childnode” comme le font l’encodage / xml. Les structures nestedes sont la voie à suivre.

Comme ce que Volker a mentionné, les structures nestedes sont la voie à suivre. Mais si vous ne voulez vraiment pas de structures nestedes, vous pouvez remplacer la fonction UnmarshalJSON.

http://play.golang.org/p/T0aZEDL0Nu

 type A struct { FooBar ssortingng // takes foo.bar FooBaz ssortingng // takes foo.baz More ssortingng `json:"more"` } func (a *A) UnmarshalJSON(b []byte) error { var f interface{} json.Unmarshal(b, &f) m := f.(map[ssortingng]interface{}) foomap := m["foo"] v := foomap.(map[ssortingng]interface{}) a.FooBar = v["bar"].(ssortingng) a.FooBaz = v["baz"].(ssortingng) return nil } 

Veuillez ignorer le fait que je ne renvoie pas une erreur correcte. Je l’ai laissé pour la simplicité.

Ceci est un exemple de comment supprimer les réponses JSON du serveur proxy sbserver de l’API Safebrowsing v4: https://play.golang.org/p/4rGB5da0Lt

 // this example shows how to unmarshall JSON requests from the Safebrowsing v4 sbserver package main import ( "fmt" "log" "encoding/json" ) // response from sbserver POST request type Results struct { Matches []Match } // nested within sbserver response type Match struct { ThreatType ssortingng PlatformType ssortingng ThreatEntryType ssortingng Threat struct { URL ssortingng } } func main() { fmt.Println("Hello, playground") // sample POST request // curl -X POST -H 'Content-Type: application/json' // -d '{"threatInfo": {"threatEnsortinges": [{"url": "http://testsafebrowsing.appspot.com/apiv4/ANY_PLATFORM/MALWARE/URL/"}]}}' // http://127.0.0.1:8080/v4/threatMatches:find // sample JSON response jsonResponse := `{"matches":[{"threatType":"MALWARE","platformType":"ANY_PLATFORM","threatEntryType":"URL","threat":{"url":"http://testsafebrowsing.appspot.com/apiv4/ANY_PLATFORM/MALWARE/URL/"}}]}` res := &Results{} err := json.Unmarshal([]byte(jsonResponse), res) if(err!=nil) { log.Fatal(err) } fmt.Printf("%v\n",res) fmt.Printf("\tThreat Type: %s\n",res.Matches[0].ThreatType) fmt.Printf("\tPlatform Type: %s\n",res.Matches[0].PlatformType) fmt.Printf("\tThreat Entry Type: %s\n",res.Matches[0].ThreatEntryType) fmt.Printf("\tURL: %s\n",res.Matches[0].Threat.URL) } 

Oui. Avec gjson, il ne vous rest plus qu’à:

bar := gjson.Get(json, "foo.bar")

bar pourrait être une propriété struct si vous le souhaitez. En outre, pas de cartes.

Qu’en est-il des champs anonymes? Je ne sais pas si cela constituera une “structure nestede”, mais c’est plus propre que d’avoir une déclaration de structure nestede. Que faire si vous voulez réutiliser l’élément nested ailleurs?

 type NestedElement struct{ someNumber int `json:"number"` someSsortingng ssortingng `json:"ssortingng"` } type BaseElement struct { NestedElement `json:"bar"` } 

oui, vous pouvez affecter les valeurs de json nested à struct jusqu’à ce que vous connaissiez le type sous-jacent des clés json, par exemple.

 package main import ( "encoding/json" "fmt" ) // Object type Object struct { Foo map[ssortingng]map[ssortingng]ssortingng `json:"foo"` More ssortingng `json:"more"` } func main(){ someJSONSsortingng := []byte(`{"foo":{ "bar": "1", "baz": "2" }, "more": "text"}`) var obj Object err := json.Unmarshal(someJSONSsortingng, &obj) if err != nil{ fmt.Println(err) } fmt.Println("jsonObj", obj) } 

Je travaillais sur quelque chose comme ça. Mais ne travaille qu’avec des structures générées à partir de proto. https://github.com/flowup-labs/grpc-utils

dans ton proto

 message Msg { Firstname ssortingng = 1 [(gogoproto.jsontag) = "name.firstname"]; PseudoFirstname ssortingng = 2 [(gogoproto.jsontag) = "lastname"]; EmbedMsg = 3 [(gogoproto.nullable) = false, (gogoproto.embed) = true]; Lastname ssortingng = 4 [(gogoproto.jsontag) = "name.lastname"]; Inside ssortingng = 5 [(gogoproto.jsontag) = "name.inside.abc"]; } message EmbedMsg{ Opt1 ssortingng = 1 [(gogoproto.jsontag) = "opt1"]; } 

Alors votre sortie sera

 { "lastname": "Three", "name": { "firstname": "One", "inside": { "a": { "b": { "c": "goo" } } }, "lastname": "Two" }, "opt1": "var" } 

La combinaison de la carte et de la structure permet de supprimer les objects JSON nesteds dont la clé est dynamic. => carte [chaîne]

Par exemple: stock.json

 { "MU": { "symbol": "MU", "title": "micro semiconductor", "share": 400, "purchase_price": 60.5, "target_price": 70 }, "LSCC":{ "symbol": "LSCC", "title": "lattice semiconductor", "share": 200, "purchase_price": 20, "target_price": 30 } } 

Aller application

 package main import ( "encoding/json" "fmt" "io/ioutil" "log" "os" ) type Stock struct { Symbol ssortingng `json:"symbol"` Title ssortingng `json:"title"` Share int `json:"share"` PurchasePrice float64 `json:"purchase_price"` TargetPrice float64 `json:"target_price"` } type Account map[ssortingng]Stock func main() { raw, err := ioutil.ReadFile("stock.json") if err != nil { fmt.Println(err.Error()) os.Exit(1) } var account Account log.Println(account) } 

La clé dynamic du hachage gère une chaîne et l’object nested est représenté par une structure.