6

I want to parse this JSON (in config/synch.conf):

{ "period" :"yy", "exec_period" : { "start" : { "month" : 1, "week" : 2, "day" : 3, "hour" : 4, "minute" : 5 }, "end" : { "month" : 6, "week" : 7, "day" : 8, "hour" : 9, "minute" : 10 } }, "backup" : [ { "local_dir" : "directoryLo1", "server_dir" : "directoryLo2", "server_host" : "domaineName" }, { "local_dir" : "directoryLo1", "server_dir" : "directorySe2", "server_host" : "domaineName" } ], "incremental_save" : "1Y2M" } 

With this programm:

package main import ( "encoding/json" "fmt" "io/ioutil" ) func main() { content, err := ioutil.ReadFile("config/synch.conf") if err == nil { type date struct{ month float64 week float64 day float64 hour float64 minute float64 } type period struct{ start date end date } type backupType []struct{ local_dir string server_dir string server_host string } type jason struct{ period string exec_period period backup backupType incremental_save string } var parsedMap jason err := json.Unmarshal(content, &parsedMap) if err!= nil { fmt.Println(err) } fmt.Println(parsedMap) } else { panic(err) } } 

Which doesn't work as expected, as the output is:

{ {{0 0 0 0 0} {0 0 0 0 0}} [] } 

Here is the same example at play.golang.org
http://play.golang.org/p/XoMJIDIV59

I don't know if this is possible with go, but I wanted to get the value of the json.Unmarshal function stored in a map[string]interface{} (or another object that allows that) where I could access, for example, the value of the minute's end (10) like this: parsedMap["exec_period"]["end"]["minute"], but I don't uderstand the "Generic JSON withinterface{}" part of JSON and Go at golang.org

1 Answer 1

13

Your code is fine except that the json package can only work with exported fields.

Everything will work if you capitalize the first letter for each field name:

type date struct { Month float64 Week float64 Day float64 Hour float64 Minute float64 } type period struct { Start date End date } type backupType []struct { Local_dir string Server_dir string Server_host string } type jason struct { Period string Exec_period period Backup backupType Incremental_save string } 

While it is possible to marshal into a map[string]interface{}, if the data has a set structure (such as the one in your question), your solution is most likely preferable. Using interface{} would require type assertions and might end up looking messy. Your example would look like this:

parsedMap["exec_period"].(map[string]interface{})["end"].(map[string]interface{})["minute"].(float64) 
Sign up to request clarification or add additional context in comments.

4 Comments

Really, was it that simple?! Thank you ANisus!
Now, my question is, how to access the value of the exec_period's minute's end? parsedMap["exec_period"]["end"]["minute"] doesn't work and replies invalid operation: parsedMap["exec_period"] (index of type jason), with first letters capitalized or not
To access the value, use parsedMap.Exec_period.End.Minute . Much cleaner than with interface type assertion! (as I added to the answer)
What if we have arbitrary data as JSON. We must use map[string]interface{}. Right? Could you give me an example of that?