Unmarshal nested JSON into flat struct in Go [duplicate]
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 go marshalling unmarshalling
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 '18 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 |
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 go marshalling unmarshalling
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 '18 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 |
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 go marshalling unmarshalling
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 go marshalling unmarshalling
json go marshalling unmarshalling
asked Nov 20 '18 at 1:10
robbieperry22robbieperry22
777
777
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 '18 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 '18 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
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 '18 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 '18 at 17:34
add a comment |
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 |
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
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 '18 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 '18 at 17:34
add a comment |
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 '18 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 '18 at 17:34
add a comment |
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 '18 at 3:36
Ehsan.SaradarEhsan.Saradar
45337
45337
Here is the Go-playground example what @Ehsan.Saradar explained: play.golang.org/p/Bn_zAsF75JV
– Abhay Kumar
Nov 20 '18 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 '18 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 '18 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 '18 at 17:34
Here is the Go-playground example what @Ehsan.Saradar explained: play.golang.org/p/Bn_zAsF75JV
– Abhay Kumar
Nov 20 '18 at 5:28
Here is the Go-playground example what @Ehsan.Saradar explained: play.golang.org/p/Bn_zAsF75JV
– Abhay Kumar
Nov 20 '18 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 '18 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 '18 at 17:34
add a comment |
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 |
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 |
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 '18 at 1:38
KibGzrKibGzr
1,466610
1,466610
add a comment |
add a comment |
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 |
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 |
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 '18 at 1:53
SlotherooSlotheroo
34018
34018
add a comment |
add a comment |