In my application, I get some unspecified json string and want to loop through the values of the json string. I use the function json.Unmarshal() to get an objectlist from the json values. That works fine. But unfortnely I get an random list of the json values and not the orginal order of them. I use this example code:
package main
import (
"encoding/json"
"fmt"
)
func main() {
jsonstr := `{
"@odata.context": "http://services.odata.org/V4/TripPinService/$metadata#People/$entity",
"@odata.id": "http://services.odata.org/V4/TripPinService/People('russellwhyte')",
"@odata.etag": "W/\"08D956FAB7E22152\"",
"@odata.editLink": "http://services.odata.org/V4/TripPinService/People('russellwhyte')",
"UserName": "russellwhyte",
"FirstName": "Russell",
"LastName": "Whyte",
"Gender": "Male",
"Concurrency": 637636457076498770
}`
var result interface{}
if err := json.Unmarshal([]byte(jsonstr), &result); err != nil {
fmt.Println("Can't convert json to object.")
fmt.Println(err.Error())
}
odataobjs := result.(map[string]interface{})
for k, v := range odataobjs {
fmt.Print(fmt.Sprintln(k, v))
}
}
See on go-playground.
This can be some of the result list:
@odata.editLink http://services.odata.org/V4/TripPinService/People('russellwhyte')
UserName russellwhyte
Gender Male
Concurrency 6.376364570764988e+17
@odata.id http://services.odata.org/V4/TripPinService/People('russellwhyte')
@odata.etag W/"08D956FAB7E22152"
LastName Whyte
@odata.context http://services.odata.org/V4/TripPinService/$metadata#People/$entity
FirstName Russell
After first search in www I find out, that a json object is in general an unordered list. Thats okay for me, as long as the list is in original order! I can't build some struct, because the json values are unknown at the runtime!
Have you some ideas for me to get the original value list?
Thanks for this input. I have now the original order. But: How can i find out the type of the values? string, nil int and float are okay and i get this. But how can i find out the arrays in the json file with this solutions? Like the following JSON, he says that Emails is an unknown type. And AddressInfo is not listet? So i can't get the sub elements from it.
Json Input:
{
"@odata.context": "http://services.odata.org/V4/TripPinService/$metadata#People",
"value": [
{
"@odata.id": "http://services.odata.org/V4/TripPinService/People('vincentcalabrese')",
"@odata.etag": "W/\"08D957CD4BA2C90E\"",
"@odata.editLink": "http://services.odata.org/V4/TripPinService/People('vincentcalabrese')",
"UserName": "vincentcalabrese",
"FirstName": "Vincent",
"LastName": "Calabrese",
"Emails": [
"Vincent@example.com",
"Vincent@contoso.com"
],
"AddressInfo": [
{
"Address": "55 Grizzly Peak Rd.",
"City": {
"CountryRegion": "United States",
"Name": "Butte",
"Region": "MT"
}
}
],
"Gender": "Male",
"Concurrency": 637637361498507534
}
]
}
Example Code:
dec := json.NewDecoder(strings.NewReader(jsonstr))
for dec.More() {
// Read prop name
t, err := dec.Token()
if err != nil {
log.Printf("Err: %v", err)
break
}
var name string
var ok bool
if name, ok = t.(string); !ok {
continue // May be a delimeter
}
// Read value:
t, err = dec.Token()
if err != nil {
log.Printf("Err: %v", err)
break
}
//fmt.Printf("Name: %s, Value: %v\n", name, t)
switch t.(type) {
case nil:
logger.Debug(fmt.Sprintf("%s is nil", name))
case string:
logger.Debug(fmt.Sprintf("%s is string", name))
case []interface{}:
logger.Debug(fmt.Sprintf("%s is array", name))
case map[string]interface{}:
logger.Debug(fmt.Sprintf("%s is map", name))
case int16:
logger.Debug(fmt.Sprintf("%s is int16", name))
case int32:
logger.Debug(fmt.Sprintf("%s is int32", name))
case int64:
logger.Debug(fmt.Sprintf("%s is int64", name))
case float32:
logger.Debug(fmt.Sprintf("%s is float32", name))
case float64:
logger.Debug(fmt.Sprintf("%s is float64", name))
default:
logger.Debug(fmt.Sprintf("%s is unknown type", name))
}
}
Output
@odata.context is string
value is unknown type
@odata.id is string
@odata.etag is string
@odata.editLink is string
UserName is string
FirstName is string
LastName is string
Emails is unknown type
Vincent@example.com is string
You have some ideas for it? Thanks you.