Getting to a specific key in JSON array using Go

go, json

Solution

The problem you have is that the function `Get` does not recursively search through the structure; it only does a look up for the key the at the current level.

What you can do is to create a recursive function that searches the structure and returns the value once it is found. Below is a working example using the standard package `encoding/json`:

package main

import (
    "encoding/json"
    "fmt"
)

// SearchNested searches a nested structure consisting of map[string]interface{}
// and []interface{} looking for a map with a specific key name.
// If found SearchNested returns the value associated with that key, true
// If the key is not found SearchNested returns nil, false
func SearchNested(obj interface{}, key string) (interface{}, bool) {
    switch t := obj.(type) {
    case map[string]interface{}:
        if v, ok := t[key]; ok {
            return v, ok
        }
        for _, v := range t {
            if result, ok := SearchNested(v, key); ok {
                return result, ok
            }
        }
    case []interface{}:
        for _, v := range t {
            if result, ok := SearchNested(v, key); ok {
                return result, ok
            }
        }
    }

    // key not found
    return nil, false
}


func main() {
    jsonData := []byte(`{
 "data": {
  "translations": [
   {
    "translatedText": "Googlebot: Deutsch, um die Luft-Speed-Geschwindigkeit einer unbeladenen Schwalbe?"
   }
  ]
 }
}`)

    // First we unmarshal into a generic interface{}
    var j interface{}
    err := json.Unmarshal(jsonData, &j)
    if err != nil {
        panic(err)
    }

    if v, ok := SearchNested(j, "translatedText"); ok {
        fmt.Printf("%+v\n", v)
    } else {
        fmt.Println("Key not found")
    }

}

Result:

Googlebot: Deutsch, um die Luft-Speed-Geschwindigkeit einer unbeladenen Schwalbe?

Playground: http://play.golang.org/p/OkLQbbId0t

Problem

I've had a heck of a time parsing JSON strings and finally landed on https://github.com/bitly/go-simplejson. It looks really promising but it's still giving me an empty result for the following JSON array: ``` { "data": { "translations": [ { "translatedText": "Googlebot: Deutsch, um die Luft-Speed-Geschwindigkeit einer unbeladenen Schwalbe?" } ] } } ``` I want to get to `translatedText` by only specifying the key. The reason for this is my JSON structure won't be predictable and so I'd like to target any JSON array but specifying a key without knowing the full structure of the JSON array. This is the snippet of code I use where `content` contains the JSON byte array: ``` f, err := js.NewJson(content) if err != nil { log.Println(err) } t := f.Get("translatedText").MustString() log.Println(t) ``` `t` is always blank :( Would appreciate any pointers.

Original source