16

I have the following code to try to Unmarshal this json file, however the line json.Unmarshal([]byte(msg["restaurant"]), &restaurant) always gives an error. How can I make Unmarshal ignore the "restaurant" or pass only the "restaurant" data to the Unmarshal function?

Thanks!

{
  "restaurant": {
    "name": "Tickets",
    "owner": {
      "name": "Ferran"
    }
  }
}


    file, e := ioutil.ReadFile("./rest_read.json")
    if e != nil {
            fmt.Println("file error")
            os.Exit(1)
    }

    var data interface{}
    json.Unmarshal(file, &data)

    msg := data.(map[string]interface{})
    log.Println(msg)
    log.Println(msg["restaurant"])
    log.Println(reflect.TypeOf(msg["restaurant"]))

    var restaurant Restaurant
    json.Unmarshal([]byte(msg["restaurant"]), &restaurant)

    log.Println("RName: ", restaurant.Name)
    log.Println("Name: ", restaurant.Owner.Name)

3 Answers 3

22

It is possible to do generic unmarshalling ala gson by decoding into an interface and then extracting a top level map from the result, e.g:

var msgMapTemplate interface{}
err := json.Unmarshal([]byte(t.ResponseBody), &msgMapTemplate)
t.AssertEqual(err, nil)
msgMap := msgMapTemplate.(map[string]interface{})

See "decoding arbitrary data" in http://blog.golang.org/json-and-go for more into.

Sign up to request clarification or add additional context in comments.

1 Comment

Good answer! Sometimes making a model to do strict Unmarshalling is a pain.
14

I would propose to construct a proper model for your data. This will enable you to cleanly unmarshal your data into a Go struct.

package main

import (
    "encoding/json"
    "fmt"
)

type Restaurant struct {
    Restaurant RestaurantData `json:"restaurant"`
}

type RestaurantData struct {
    Name  string `json:"name"`
    Owner Owner  `json:"owner"`
}

type Owner struct {
    Name string `json:"name"`
}

func main() {
    data := `{"restaurant":{"name":"Tickets","owner":{"name":"Ferran"}}}`
    r := Restaurant{}
    json.Unmarshal([]byte(data), &r)

    fmt.Printf("%+v", r)
}

Comments

2

Unmarshalling occurs recursively, so msg["restaurant"] is no longer a json string - it is another map[string]interface{}. If you want to unmarshall directly into a Restaurant object, you will have to provide a simple wrapper object with a Restaurant member and unmarshall into that.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.