Parse a json string using struct

I am trrying to parse the below json string

     {
    	"BookDocuments": ["{\"Book_id\":\"1-5f0171f2-000000000000000000000000\",\"id\":\"0100000000000000\",\"name\":\"words-generator-span\",\"start_time\":1593930226.651007,\"end_time\":1593930226.6520069,\"origin\":\"library::shelf::Author\",\"type\":\"sub\",\"namespace\":\"remote\",\"library\":{},\"annotations\":{\"words_generator_span_seq_num\":\"\",\"words_generator_Book_seq_num\":\"\"}}\n", "{\"Book_id\":\"1-5f0171f2-000000000000000000000000\",\"id\":\"0200000000000000\",\"name\":\"words-generator-span\",\"start_time\":1593930226.651019,\"end_time\":1593930226.652019,\"origin\":\"library::shelf::Author\",\"type\":\"sub\",\"namespace\":\"remote\",\"library\":{},\"annotations\":{\"words_generator_span_seq_num\":\"\",\"words_generator_Book_seq_num\":\"\"}}\n", "{\"Book_id\":\"1-5f0171f2-000000000000000000000000\",\"id\":\"0300000000000000\",\"name\":\"words-generator-span\",\"start_time\":1593930226.65102,\"end_time\":1593930226.65202,\"origin\":\"library::shelf::Author\",\"type\":\"sub\",\"namespace\":\"remote\",\"library\":{},\"annotations\":{\"words_generator_span_seq_num\":\"\",\"words_generator_Book_seq_num\":\"\"}}\n", "{\"Book_id\":\"1-5f0171f2-000000000000000000000000\",\"id\":\"0400000000000000\",\"name\":\"words-generator-span\",\"start_time\":1593930226.651021,\"end_time\":1593930226.652021,\"origin\":\"library::shelf::Author\",\"type\":\"sub\",\"namespace\":\"remote\",\"library\":{},\"annotations\":{\"words_generator_span_seq_num\":\"\",\"words_generator_Book_seq_num\":\"\"}}\n", "{\"Book_id\":\"1-5f0171f2-000000000000000000000000\",\"id\":\"0500000000000000\",\"name\":\"words-generator-span\",\"start_time\":1593930226.651021,\"end_time\":1593930226.652021,\"origin\":\"library::shelf::Author\",\"type\":\"sub\",\"namespace\":\"remote\",\"library\":{},\"annotations\":{\"words_generator_span_seq_num\":\"\",\"words_generator_Book_seq_num\":\"\"}}\n"]
    }

and below are my structs

    type BookDocuments struct {
    	BookDocuments []Documents `json:"BookDocuments,omitempty"`
    }

type Documents struct {
	Book_id     string                 `json:"Book_id,omitempty"`
	ID          string                 `json:"id"`
	Name        string                 `json:"name"`
	StartTime   float64                `json:"start_time"`
	EndTime     float64                `json:"end_time,omitempty"`
	Origin      string                 `json:"origin,omitempty"`
	Type        string                 `json:"type,omitempty"`
	Namespace   string                 `json:"namespace,omitempty"`
	library     Info                `json:"Info,omitempty"`
	Annotations map[string]interface{} `json:"annotations,omitempty"`
}

type Info struct {
	AccountID    string `json:"account_id,omitempty"`
	Operation    string `json:"operation,omitempty"`
	RemoteRegion string `json:"region,omitempty"`
	RequestID    string `json:"request_id,omitempty"`
	QueueURL     string `json:"queue_url,omitempty"`
	TableName    string `json:"table_name,omitempty"`
}

when I try to unmarshall it i get empt array, anybidy How Can I do it?

below is the link where I tried to run it
https://play.golang.org/p/R97eh7tkgrq

1 Like

It seems as if the "BookDocuments" does not contain JSON objects but strings. You probably need to implement json.Unmarshaller to unwrap that string nesting.

1 Like

can you help me with some example how it can be done.

1 Like

Hey Shreyas!

Here an example of how to implement a custom Unmarshler method: https://play.golang.org/p/otPTEGUzcaE

func main() {
bookDocuments := `{"BookDocuments": ["{\"Book_id\":\"1-5f0171f2-000000000000000000000000\",\"id\":\"0100000000000000\",\"name\":\"words-generator-span\",\"start_time\":1593930226.651007,\"end_time\":1593930226.6520069,\"origin\":\"library::shelf::Author\",\"type\":\"sub\",\"namespace\":\"remote\",\"library\":{},\"annotations\":{\"words_generator_span_seq_num\":\"\",\"words_generator_Book_seq_num\":\"\"}}\n", "{\"Book_id\":\"1-5f0171f2-000000000000000000000000\",\"id\":\"0200000000000000\",\"name\":\"words-generator-span\",\"start_time\":1593930226.651019,\"end_time\":1593930226.652019,\"origin\":\"library::shelf::Author\",\"type\":\"sub\",\"namespace\":\"remote\",\"library\":{},\"annotations\":{\"words_generator_span_seq_num\":\"\",\"words_generator_Book_seq_num\":\"\"}}\n", "{\"Book_id\":\"1-5f0171f2-000000000000000000000000\",\"id\":\"0300000000000000\",\"name\":\"words-generator-span\",\"start_time\":1593930226.65102,\"end_time\":1593930226.65202,\"origin\":\"library::shelf::Author\",\"type\":\"sub\",\"namespace\":\"remote\",\"library\":{},\"annotations\":{\"words_generator_span_seq_num\":\"\",\"words_generator_Book_seq_num\":\"\"}}\n", "{\"Book_id\":\"1-5f0171f2-000000000000000000000000\",\"id\":\"0400000000000000\",\"name\":\"words-generator-span\",\"start_time\":1593930226.651021,\"end_time\":1593930226.652021,\"origin\":\"library::shelf::Author\",\"type\":\"sub\",\"namespace\":\"remote\",\"library\":{},\"annotations\":{\"words_generator_span_seq_num\":\"\",\"words_generator_Book_seq_num\":\"\"}}\n", "{\"Book_id\":\"1-5f0171f2-000000000000000000000000\",\"id\":\"0500000000000000\",\"name\":\"words-generator-span\",\"start_time\":1593930226.651021,\"end_time\":1593930226.652021,\"origin\":\"library::shelf::Author\",\"type\":\"sub\",\"namespace\":\"remote\",\"library\":{},\"annotations\":{\"words_generator_span_seq_num\":\"\",\"words_generator_Book_seq_num\":\"\"}}\n"]}`

var bd BookDocuments
if err := json.Unmarshal([]byte(bookDocuments), &bd); err != nil {
	panic(err)
}
fmt.Println(bd)
}

func (bd *BookDocuments) UnmarshalJSON(b []byte) error {
d := map[string][]string{}
if err := json.Unmarshal(b, &d); err != nil {
	return err
}
dd := []Documents{}

for _, bd := range d["BookDocuments"] {
	d := Documents{}
	if err := json.Unmarshal([]byte(bd), &d); err != nil {
		panic(err)
	}
	dd = append(dd, d)
}

fmt.Println(dd)

fmt.Println(dd[0].Name)

return nil
}

My example isn’t the greatest implementation of how you could do this, but hopefully it will give you a starting point.

Thanks