Unmarshalling JSON, which may or may not return an array?

I pick up JSON from a third-party site (using home consumption), and depending on what I requested on the site, the returned JSON may or may not be an array. For example, if I request a list of my smart meters, I get this (results are truncated due to the large size):

{"gwrcmds":{"gwrcmd":{"gcmd":"SPA_UserGetSmartMeterList","gdata":{"gip":{"version":"1"...

Where gwrcmd is one element.

But if I ask for the use of electricity in the last hour and a half, I get the following:

{"gwrcmds":{"gwrcmd":[{"gcmd":"DeviceGetChart","gdata":{"gip":{"version":"1" ...

See how gwrcmd is now an array?

In my Go app, I have a structure that looks like this (again, truncated as it has been going on for some time). There are more substructures and properties below the "Version":

type Response struct {
    Gwrcmds struct {
        Gwrcmd struct {
            Gcmd  string
            Gdata struct {
                Gip struct {
                    Version string

gwrcmd - , gwrcmd []struct { }, , struct { }

, json.Unmarshal , JSON , ( ).

, ( []struct { }), ? - , , 100%.

+3
2

, JSON, json.RawMessage, , . :

// The A here can be either an object, or a JSON array of objects.
type Response struct {
    RawAWrapper struct {
        RawA json.RawMessage `json:"a"`
    }
    A  A   `json:"-"`
    As []A `json:"-"`
}

type A struct {
    B string
}

func (r *Response) UnmarshalJSON(b []byte) error {
    if err := json.Unmarshal(b, &r.RawAWrapper); err != nil {
        return err
    }
    if r.RawAWrapper.RawA[0] == '[' {
        return json.Unmarshal(r.RawAWrapper.RawA, &r.As)
    }
    return json.Unmarshal(r.RawAWrapper.RawA, &r.A)
}

: http://play.golang.org/p/2d_OrGltDu.

, , , . - JSON (, length type , ), , .

. :

+6

json unmarshal,

func (a *GwrcmCustom) UnmarshalJSON(b []byte) (err error) {
    g, ga := Gwrcmd{}, []Gwrcmd{}
    if err = json.Unmarshal(b, &g); err == nil {
        *a = make([]Gwrcmd, 1)
        []Gwrcmd(*a)[0] = Gwrcmd(g)
        return
    }
    if err = json.Unmarshal(b, &ga); err == nil {
        *a = GwrcmCustom(ga)
        return
    }
    return
}

GwrcmCustom - , Gwrcm

type GwrcmCustom []Gwrcmd

,

,

+1

All Articles