В общем, для подобных случаев вам придется использовать общую способность демаршалинга json.Unmarshal
в interface{}
.
b := []byte(`{ "key1": { "key2": { "key3": "Found data" } } } `)
var f interface{}
if err := json.Unmarshal(b, &f); err != nil {
panic(err)
}
fmt.Println(f)
И теперь вы можете использовать группу утверждений типа для исследования f
, например, чтобы найти, какие ключи в нем содержатся:
m := f.(map[string]interface{})
for k, v := range m {
if k == "key3" {
fmt.Println("found key3. maps to", v)
}
}
Если вы не нашли ключ 3 на этом уровне, используйте рекурсию для проверки всех значений - они сопоставлены с ключами key3 и т. Д. Что-то вроде
func findNested(m map[string]interface{}, s string) (bool, interface{}) {
// Try to find key s at this level
for k, v := range m {
if k == s {
return true, v
}
}
// Not found on this level, so try to find it nested
for _, v := range m {
nm := v.(map[string]interface{})
found, val := findNested(nm, s)
if found {
return found, val
}
}
// Not found recursively
return false, nil
}
Примечание: эта функция была быстро взломана и, вероятно, неправильно обрабатывает множество угловых случаев. Это здесь, чтобы продемонстрировать ключевую идею - использовать ее в качестве основы для ваших конкретных потребностей