Usman Ismail
Usman Ismail

Reputation: 18679

How can I ignore root JSON Element in go?

I would like to serialize the following JSON into a map[string]string with map["Name"] == "Value"

{
    "Item": {
        "tags": {
            "Name": "Value"
        }
    }
}

However, I want to not have to create a strut with one field for "item". Is it possible to ignore the root JSON element in go similar to Java/Jackson: mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);

The best I have so far is:

items := make(map[string]map[string]string)
items := items["Item"]

Upvotes: 4

Views: 1983

Answers (2)

gbin
gbin

Reputation: 3000

I would make a small helper that will skip the root of the structure around the lines of:

func SkipRoot(jsonBlob []byte) json.RawMessage {
    var root map[string]json.RawMessage

    if err := json.Unmarshal(jsonBlob, &root); err != nil {
        panic(err)
    }
    for _, v := range root {
        return v
    }
    return nil
}

Then use it like that :

json.Unmarshal(SkipRoot(jsonBlob), &items)

Full example here : Playground

Upvotes: 6

ANisus
ANisus

Reputation: 78075

Unfortunately, no.
The encoding/json package doesn't have any feature allowing you to ignore the root element. The easiest way is to use those unwanted structs you mentioned:

type Root struct {
    Item Item
}

type Item struct {
    Tags map[string]string
}

Here is a full working example:

package main

import (
    "encoding/json"
    "fmt"
)

type Root struct {
    Item Item
}

type Item struct {
    Tags map[string]string
}

var data = []byte(`{
    "Item": {
        "tags": {
            "Name": "Value"
        }
    }
}`)

func main() {    
    var s Root
    if err := json.Unmarshal(data, &s); err != nil {
        panic(err)
    }

    tags := s.Item.Tags
    fmt.Printf("%+v", tags)
}

Output

map[Name:Value]

Playground

Upvotes: 1

Related Questions