Unmarshal nested JSON into flat struct in Go [duplicate]
up vote
-1
down vote
favorite
This question already has an answer here:
Unmarshaling nested JSON objects in Golang
8 answers
Suppose I define a struct as following:
type User struct {
ID string
Name string
Age uint
City string `json:"address.city"`
Province string `json:"address.province"`
}
I am able to take a User struct, and expand out the flattened fiends into a nested JSON structure, with an address object. I'm struggling however to go in the other direction.
How would I take the following JSON:
{
"ID": "1",
"Name": "Keith Baldwin",
"Age": 30,
"address": {
"city": "Saskatoon",
"province": "Saskatchewan"
}
}
And unmarshal it into the given struct?
Is there something I'm missing, or will I just have to write it from scratch, probably using reflection?
Thanks
json
marked as duplicate by Volker
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 20 at 5:55
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
add a comment |
up vote
-1
down vote
favorite
This question already has an answer here:
Unmarshaling nested JSON objects in Golang
8 answers
Suppose I define a struct as following:
type User struct {
ID string
Name string
Age uint
City string `json:"address.city"`
Province string `json:"address.province"`
}
I am able to take a User struct, and expand out the flattened fiends into a nested JSON structure, with an address object. I'm struggling however to go in the other direction.
How would I take the following JSON:
{
"ID": "1",
"Name": "Keith Baldwin",
"Age": 30,
"address": {
"city": "Saskatoon",
"province": "Saskatchewan"
}
}
And unmarshal it into the given struct?
Is there something I'm missing, or will I just have to write it from scratch, probably using reflection?
Thanks
json
marked as duplicate by Volker
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 20 at 5:55
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
add a comment |
up vote
-1
down vote
favorite
up vote
-1
down vote
favorite
This question already has an answer here:
Unmarshaling nested JSON objects in Golang
8 answers
Suppose I define a struct as following:
type User struct {
ID string
Name string
Age uint
City string `json:"address.city"`
Province string `json:"address.province"`
}
I am able to take a User struct, and expand out the flattened fiends into a nested JSON structure, with an address object. I'm struggling however to go in the other direction.
How would I take the following JSON:
{
"ID": "1",
"Name": "Keith Baldwin",
"Age": 30,
"address": {
"city": "Saskatoon",
"province": "Saskatchewan"
}
}
And unmarshal it into the given struct?
Is there something I'm missing, or will I just have to write it from scratch, probably using reflection?
Thanks
json
This question already has an answer here:
Unmarshaling nested JSON objects in Golang
8 answers
Suppose I define a struct as following:
type User struct {
ID string
Name string
Age uint
City string `json:"address.city"`
Province string `json:"address.province"`
}
I am able to take a User struct, and expand out the flattened fiends into a nested JSON structure, with an address object. I'm struggling however to go in the other direction.
How would I take the following JSON:
{
"ID": "1",
"Name": "Keith Baldwin",
"Age": 30,
"address": {
"city": "Saskatoon",
"province": "Saskatchewan"
}
}
And unmarshal it into the given struct?
Is there something I'm missing, or will I just have to write it from scratch, probably using reflection?
Thanks
This question already has an answer here:
Unmarshaling nested JSON objects in Golang
8 answers
json
json
asked Nov 20 at 1:10
robbieperry22
286
286
marked as duplicate by Volker
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 20 at 5:55
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
marked as duplicate by Volker
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Nov 20 at 5:55
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
up vote
1
down vote
Create userInfo class
type UserInfo struct {
ID string `json:"ID"`
Name string `json:"Name"`
Age int `json:"Age"`
Address struct {
City string `json:"city"`
Province string `json:"province"`
} `json:"address"`
}
Then unmarshal your json data into a userinfo object
var userInfo UserInfo
jsonStr := `{
"ID": "1",
"Name": "Keith Baldwin",
"Age": 30,
"address": {
"city": "Saskatoon",
"province": "Saskatchewan"
}
}`
json.Unmarshal(byte(jsonStr), &userInfo)
Here is the Go-playground example what @Ehsan.Saradar explained: play.golang.org/p/Bn_zAsF75JV
– Abhay Kumar
Nov 20 at 5:28
Thanks for the note. Unfortunately this won't work for me, as I need to be able to do it for any arbitrary data structure, and only flatten fields defined in the struct asjson:"something.something".
– robbieperry22
Nov 20 at 17:34
add a comment |
up vote
0
down vote
I think you need create an other Address struct.
type Address struct {
City string `json:"city"`
Province string `json:"province"`
}
type User struct {
ID string `json:"id"`
Name string `json:"name"`
Age uint `json:"age"`
Address Address `json:"address"`
}
add a comment |
up vote
0
down vote
You could make a temporary struct type to dump that data into that matches the format you expect. e.g.
type userData struct {
ID string
Name string
Age uint
address map[string]string
}
Although my favorite thing to do is to just dump all of the json into a map with string keys and json.RawMessage as values. This will allow you to unmarshal all of the json into this map, and then unmarshal each individual field however you would want.
var allData map[string]json.RawMessage
var user User{}
//Assuming we first get our json from a request, otherwise use json.Unmarshal(jsonData, &allData)
err := json.NewDecoder(r.Body).Decode(&allData)
if err != nil {
//handle
}
err = json.Unmarshal(allData["ID"], &c.ID)
if err != nil {
//handle
}
var addressMap map[string]string
err = json.Unmarshal(allData["address"], addressMap)
if err != nil {
//handle
}
c.City = addressMap["city"]
c.Province = addressMap["province"]
I haven't tested any of that code, so it may be error ridden, but it's just meant to convey the idea of converting all of the data into a map of json.RawMessage values and then unmarshalling each property. Normally you'd have a lot more error checking to see if values exist, etc. It's more work, for sure, but it's incredibly flexible and gives you a lot of visibility and power into how the data is handled as opposed to just unmarshalling into a struct and hoping the magic works.
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
Create userInfo class
type UserInfo struct {
ID string `json:"ID"`
Name string `json:"Name"`
Age int `json:"Age"`
Address struct {
City string `json:"city"`
Province string `json:"province"`
} `json:"address"`
}
Then unmarshal your json data into a userinfo object
var userInfo UserInfo
jsonStr := `{
"ID": "1",
"Name": "Keith Baldwin",
"Age": 30,
"address": {
"city": "Saskatoon",
"province": "Saskatchewan"
}
}`
json.Unmarshal(byte(jsonStr), &userInfo)
Here is the Go-playground example what @Ehsan.Saradar explained: play.golang.org/p/Bn_zAsF75JV
– Abhay Kumar
Nov 20 at 5:28
Thanks for the note. Unfortunately this won't work for me, as I need to be able to do it for any arbitrary data structure, and only flatten fields defined in the struct asjson:"something.something".
– robbieperry22
Nov 20 at 17:34
add a comment |
up vote
1
down vote
Create userInfo class
type UserInfo struct {
ID string `json:"ID"`
Name string `json:"Name"`
Age int `json:"Age"`
Address struct {
City string `json:"city"`
Province string `json:"province"`
} `json:"address"`
}
Then unmarshal your json data into a userinfo object
var userInfo UserInfo
jsonStr := `{
"ID": "1",
"Name": "Keith Baldwin",
"Age": 30,
"address": {
"city": "Saskatoon",
"province": "Saskatchewan"
}
}`
json.Unmarshal(byte(jsonStr), &userInfo)
Here is the Go-playground example what @Ehsan.Saradar explained: play.golang.org/p/Bn_zAsF75JV
– Abhay Kumar
Nov 20 at 5:28
Thanks for the note. Unfortunately this won't work for me, as I need to be able to do it for any arbitrary data structure, and only flatten fields defined in the struct asjson:"something.something".
– robbieperry22
Nov 20 at 17:34
add a comment |
up vote
1
down vote
up vote
1
down vote
Create userInfo class
type UserInfo struct {
ID string `json:"ID"`
Name string `json:"Name"`
Age int `json:"Age"`
Address struct {
City string `json:"city"`
Province string `json:"province"`
} `json:"address"`
}
Then unmarshal your json data into a userinfo object
var userInfo UserInfo
jsonStr := `{
"ID": "1",
"Name": "Keith Baldwin",
"Age": 30,
"address": {
"city": "Saskatoon",
"province": "Saskatchewan"
}
}`
json.Unmarshal(byte(jsonStr), &userInfo)
Create userInfo class
type UserInfo struct {
ID string `json:"ID"`
Name string `json:"Name"`
Age int `json:"Age"`
Address struct {
City string `json:"city"`
Province string `json:"province"`
} `json:"address"`
}
Then unmarshal your json data into a userinfo object
var userInfo UserInfo
jsonStr := `{
"ID": "1",
"Name": "Keith Baldwin",
"Age": 30,
"address": {
"city": "Saskatoon",
"province": "Saskatchewan"
}
}`
json.Unmarshal(byte(jsonStr), &userInfo)
answered Nov 20 at 3:36
Ehsan.Saradar
45327
45327
Here is the Go-playground example what @Ehsan.Saradar explained: play.golang.org/p/Bn_zAsF75JV
– Abhay Kumar
Nov 20 at 5:28
Thanks for the note. Unfortunately this won't work for me, as I need to be able to do it for any arbitrary data structure, and only flatten fields defined in the struct asjson:"something.something".
– robbieperry22
Nov 20 at 17:34
add a comment |
Here is the Go-playground example what @Ehsan.Saradar explained: play.golang.org/p/Bn_zAsF75JV
– Abhay Kumar
Nov 20 at 5:28
Thanks for the note. Unfortunately this won't work for me, as I need to be able to do it for any arbitrary data structure, and only flatten fields defined in the struct asjson:"something.something".
– robbieperry22
Nov 20 at 17:34
Here is the Go-playground example what @Ehsan.Saradar explained: play.golang.org/p/Bn_zAsF75JV
– Abhay Kumar
Nov 20 at 5:28
Here is the Go-playground example what @Ehsan.Saradar explained: play.golang.org/p/Bn_zAsF75JV
– Abhay Kumar
Nov 20 at 5:28
Thanks for the note. Unfortunately this won't work for me, as I need to be able to do it for any arbitrary data structure, and only flatten fields defined in the struct as
json:"something.something".– robbieperry22
Nov 20 at 17:34
Thanks for the note. Unfortunately this won't work for me, as I need to be able to do it for any arbitrary data structure, and only flatten fields defined in the struct as
json:"something.something".– robbieperry22
Nov 20 at 17:34
add a comment |
up vote
0
down vote
I think you need create an other Address struct.
type Address struct {
City string `json:"city"`
Province string `json:"province"`
}
type User struct {
ID string `json:"id"`
Name string `json:"name"`
Age uint `json:"age"`
Address Address `json:"address"`
}
add a comment |
up vote
0
down vote
I think you need create an other Address struct.
type Address struct {
City string `json:"city"`
Province string `json:"province"`
}
type User struct {
ID string `json:"id"`
Name string `json:"name"`
Age uint `json:"age"`
Address Address `json:"address"`
}
add a comment |
up vote
0
down vote
up vote
0
down vote
I think you need create an other Address struct.
type Address struct {
City string `json:"city"`
Province string `json:"province"`
}
type User struct {
ID string `json:"id"`
Name string `json:"name"`
Age uint `json:"age"`
Address Address `json:"address"`
}
I think you need create an other Address struct.
type Address struct {
City string `json:"city"`
Province string `json:"province"`
}
type User struct {
ID string `json:"id"`
Name string `json:"name"`
Age uint `json:"age"`
Address Address `json:"address"`
}
answered Nov 20 at 1:38
KibGzr
1,102510
1,102510
add a comment |
add a comment |
up vote
0
down vote
You could make a temporary struct type to dump that data into that matches the format you expect. e.g.
type userData struct {
ID string
Name string
Age uint
address map[string]string
}
Although my favorite thing to do is to just dump all of the json into a map with string keys and json.RawMessage as values. This will allow you to unmarshal all of the json into this map, and then unmarshal each individual field however you would want.
var allData map[string]json.RawMessage
var user User{}
//Assuming we first get our json from a request, otherwise use json.Unmarshal(jsonData, &allData)
err := json.NewDecoder(r.Body).Decode(&allData)
if err != nil {
//handle
}
err = json.Unmarshal(allData["ID"], &c.ID)
if err != nil {
//handle
}
var addressMap map[string]string
err = json.Unmarshal(allData["address"], addressMap)
if err != nil {
//handle
}
c.City = addressMap["city"]
c.Province = addressMap["province"]
I haven't tested any of that code, so it may be error ridden, but it's just meant to convey the idea of converting all of the data into a map of json.RawMessage values and then unmarshalling each property. Normally you'd have a lot more error checking to see if values exist, etc. It's more work, for sure, but it's incredibly flexible and gives you a lot of visibility and power into how the data is handled as opposed to just unmarshalling into a struct and hoping the magic works.
add a comment |
up vote
0
down vote
You could make a temporary struct type to dump that data into that matches the format you expect. e.g.
type userData struct {
ID string
Name string
Age uint
address map[string]string
}
Although my favorite thing to do is to just dump all of the json into a map with string keys and json.RawMessage as values. This will allow you to unmarshal all of the json into this map, and then unmarshal each individual field however you would want.
var allData map[string]json.RawMessage
var user User{}
//Assuming we first get our json from a request, otherwise use json.Unmarshal(jsonData, &allData)
err := json.NewDecoder(r.Body).Decode(&allData)
if err != nil {
//handle
}
err = json.Unmarshal(allData["ID"], &c.ID)
if err != nil {
//handle
}
var addressMap map[string]string
err = json.Unmarshal(allData["address"], addressMap)
if err != nil {
//handle
}
c.City = addressMap["city"]
c.Province = addressMap["province"]
I haven't tested any of that code, so it may be error ridden, but it's just meant to convey the idea of converting all of the data into a map of json.RawMessage values and then unmarshalling each property. Normally you'd have a lot more error checking to see if values exist, etc. It's more work, for sure, but it's incredibly flexible and gives you a lot of visibility and power into how the data is handled as opposed to just unmarshalling into a struct and hoping the magic works.
add a comment |
up vote
0
down vote
up vote
0
down vote
You could make a temporary struct type to dump that data into that matches the format you expect. e.g.
type userData struct {
ID string
Name string
Age uint
address map[string]string
}
Although my favorite thing to do is to just dump all of the json into a map with string keys and json.RawMessage as values. This will allow you to unmarshal all of the json into this map, and then unmarshal each individual field however you would want.
var allData map[string]json.RawMessage
var user User{}
//Assuming we first get our json from a request, otherwise use json.Unmarshal(jsonData, &allData)
err := json.NewDecoder(r.Body).Decode(&allData)
if err != nil {
//handle
}
err = json.Unmarshal(allData["ID"], &c.ID)
if err != nil {
//handle
}
var addressMap map[string]string
err = json.Unmarshal(allData["address"], addressMap)
if err != nil {
//handle
}
c.City = addressMap["city"]
c.Province = addressMap["province"]
I haven't tested any of that code, so it may be error ridden, but it's just meant to convey the idea of converting all of the data into a map of json.RawMessage values and then unmarshalling each property. Normally you'd have a lot more error checking to see if values exist, etc. It's more work, for sure, but it's incredibly flexible and gives you a lot of visibility and power into how the data is handled as opposed to just unmarshalling into a struct and hoping the magic works.
You could make a temporary struct type to dump that data into that matches the format you expect. e.g.
type userData struct {
ID string
Name string
Age uint
address map[string]string
}
Although my favorite thing to do is to just dump all of the json into a map with string keys and json.RawMessage as values. This will allow you to unmarshal all of the json into this map, and then unmarshal each individual field however you would want.
var allData map[string]json.RawMessage
var user User{}
//Assuming we first get our json from a request, otherwise use json.Unmarshal(jsonData, &allData)
err := json.NewDecoder(r.Body).Decode(&allData)
if err != nil {
//handle
}
err = json.Unmarshal(allData["ID"], &c.ID)
if err != nil {
//handle
}
var addressMap map[string]string
err = json.Unmarshal(allData["address"], addressMap)
if err != nil {
//handle
}
c.City = addressMap["city"]
c.Province = addressMap["province"]
I haven't tested any of that code, so it may be error ridden, but it's just meant to convey the idea of converting all of the data into a map of json.RawMessage values and then unmarshalling each property. Normally you'd have a lot more error checking to see if values exist, etc. It's more work, for sure, but it's incredibly flexible and gives you a lot of visibility and power into how the data is handled as opposed to just unmarshalling into a struct and hoping the magic works.
answered Nov 20 at 1:53
Slotheroo
33018
33018
add a comment |
add a comment |