-
-
Save md2k/ec292658ac1923135c40f616cc78329b to your computer and use it in GitHub Desktop.
Parse JSON objects with arbitrary key names in Go using interfaces and type assertions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Parsing arbitrary JSON using interfaces in Go | |
// Demonstrates how to parse JSON with abritrary key names | |
// See https://blog.golang.org/json-and-go for more info on generic JSON parsing | |
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
) | |
var jsonBytes = []byte(` | |
{ | |
"key1":{ | |
"Item1": "Value1", | |
"Item2": 1}, | |
"key2":{ | |
"Item1": "Value2", | |
"Item2": 2}, | |
"key3":{ | |
"Item1": "Value3", | |
"Item2": 3} | |
}`) | |
// Item struct; we want to create these from the JSON above | |
type Item struct { | |
Item1 string | |
Item2 int | |
} | |
// Implement the String interface for pretty printing Items | |
func (i Item) String() string { | |
return fmt.Sprintf("Item: %s, %d", i.Item1, i.Item2) | |
} | |
func main() { | |
// Unmarshal using a generic interface | |
var f interface{} | |
err := json.Unmarshal(jsonBytes, &f) | |
if err != nil { | |
fmt.Println("Error parsing JSON: ", err) | |
} | |
// JSON object parses into a map with string keys | |
itemsMap := f.(map[string]interface{}) | |
// Loop through the Items; we're not interested in the key, just the values | |
for _, v := range itemsMap { | |
// Use type assertions to ensure that the value's a JSON object | |
switch jsonObj := v.(type) { | |
// The value is an Item, represented as a generic interface | |
case interface{}: | |
var item Item | |
// Access the values in the JSON object and place them in an Item | |
for itemKey, itemValue := range jsonObj.(map[string]interface{}) { | |
switch itemKey { | |
case "Item1": | |
// Make sure that Item1 is a string | |
switch itemValue := itemValue.(type) { | |
case string: | |
item.Item1 = itemValue | |
default: | |
fmt.Println("Incorrect type for", itemKey) | |
} | |
case "Item2": | |
// Make sure that Item2 is a number; all numbers are transformed to float64 | |
switch itemValue := itemValue.(type) { | |
case float64: | |
item.Item2 = int(itemValue) | |
default: | |
fmt.Println("Incorrect type for", itemKey) | |
} | |
default: | |
fmt.Println("Unknown key for Item found in JSON") | |
} | |
} | |
fmt.Println(item) | |
// Not a JSON object; handle the error | |
default: | |
fmt.Println("Expecting a JSON object; got something else") | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment