How to get a JSON unique field's name and deeply nested child field's value in Golang?
How to get a JSON unique field's name and deeply nested child field's value in Golang?
I have a json file that looks like this
{
"links": {
"uniqueurl_1": {
"a": {
"b": [
"stuff"
],
"I": {
"want": {
"to": "morestuff",
"go": {
"in": {
"here": {
"and": "array",
"itis": {
"very": "string",
"deep": "stringIwant"
}
}
}
}
}
}
}
}
}
}
And I want to get the uniqueurl_1
(that is always different for each link), and I also want to get the "deep" field's value ("stringIwant")
uniqueurl_1
I know if it's not too deeply nested, you can just create a bunch of structs in Golang, but when it's this deep would it still be the only/best way to do it?
uniqueurl_1
2 Answers
2
in your JSON is missing opening brace.
Have a try in this way:
{
"links": {
"uniqueurl_1": {
"a": {
"b": [
"stuff"
],
"I": {
"want": {
"to": "morestuff",
"go": {
"in": {
"here": {
"and": "array",
"itis": {
"very": "string",
"deep": "stringIwant"
}
}
}
}
}
}
}
}
}
}
And use the following code to access you data:
package main
import "encoding/json"
func UnmarshalNotSoDeep(data byte) (NotSoDeep, error) {
var r NotSoDeep
err := json.Unmarshal(data, &r)
return r, err
}
func (r *NotSoDeep) Marshal() (byte, error) {
return json.Marshal(r)
}
type NotSoDeep struct {
Links Links `json:"links"`
}
type Links struct {
Uniqueurl1 Uniqueurl1 `json:"uniqueurl_1"`
}
type Uniqueurl1 struct {
A A `json:"a"`
}
type A struct {
B string `json:"b"`
I I `json:"I"`
}
type I struct {
Want Want `json:"want"`
}
type Want struct {
To string `json:"to"`
Go Go `json:"go"`
}
type Go struct {
In In `json:"in"`
}
type In struct {
Here Here `json:"here"`
}
type Here struct {
And string `json:"and"`
Itis Itis `json:"itis"`
}
type Itis struct {
Very string `json:"very"`
Deep string `json:"deep"`
}
so basically the "create a legion of structs" type of thing? Kinda not Golang related but would a different language say python be better at constructing this thing? (Json->Json (modified))
– Igeneous
Jun 30 at 8:28
Both solutions, Golang and Python, are long, at first look Go is more readable. Choose the one you prefer.
– Danilo
Jun 30 at 8:56
Hi, it looks like this solution can deeply go into my structure, but the issue is each of my links are unique. Say I have another "uniqueurl_2" (not named 1, 2, 3... of course), then when I run the code I won't get uniqueurl_2. Does this mean I'd have to make a separate struct to contain each and every "uniqueurl_N" field?
– Igeneous
21 hours ago
Well, you can implement an array of links, replace the
Links
struct as follow: type Links struct { Uniqueurl1 Uniqueurl1
json:"uniqueurl_1"` }`– Danilo
21 hours ago
Links
type Links struct { Uniqueurl1 Uniqueurl1
Won't I have an array of Uniqueurl1's though, and I want to have a Uniqueurl1, 2, 3, etc. The Links struct you provided contains an array of objects all of type Uniqueurl1 right?
– Igeneous
21 hours ago
For this case you can use gojsonq - A simple Go package to Query over JSON Data library.
Here is full list of available queries.
So if you want get the value (stringIwant
), you can choose or method From or method Find.
stringIwant
Example below:
package main
import (
"fmt"
"github.com/thedevsaddam/gojsonq"
)
const json = `{
"links": {
"uniqueurl_1": {
"a": {
"b": [
"stuff"
],
"I": {
"want": {
"to": "morestuff",
"go": {
"in": {
"here": {
"and": "array",
"itis": {
"very": "string",
"deep": "stringIwant"
}
}
}
}
}
}
}
}
}
}`
func main() {
key := "uniqueurl_1"
query := "links." + key + ".a.I.want.go.in.here.itis.deep"
fmt.Println(gojsonq.New().JSONString(json).From(query).Get())
fmt.Println(gojsonq.New().JSONString(json).Find(query).(string))
}
Output:
stringIwant
stringIwant
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
you can unmarshal any nested json by creating nested struct. The only thing is dynamic value of
uniqueurl_1
, for that you can create interface{}.– Himanshu
Jun 30 at 6:34