2016-10-07 71 views
2

我的输入JSON有一个不同元素的列表。
我有第一个响应元素的数量有问题。Golang Unmarshal JSON

Simplified example

package main 

import (
    "fmt" 
    "log" 
    "encoding/json" 
) 

var j = ` { 
    "response": [ 
    777, // problem here !!! 
    { 
     "id": 888, 
     "from_id": 999, 
     "to_id": 888, 
     "text": "hello..." 
    }, 
     { 
     "id": 999, 
     "from_id": 888, 
     "to_id": 999, 
      "text": "goodbye..." 
    } 
    ] 
}` 

type D struct { 
    Id  int `json:"id"` 
    FromId int `json:"from_id"` 
    ToId int `json:"to_id"` 
    Text string `json:"text"` 
} 

type R struct { 
    Count int 
    Response []D `json:"response"` 
} 

func main() { 
    var data = new(R) 
    err := json.Unmarshal([]byte(j), &data) 
    if err != nil { 
     log.Fatal(err) 
    } 
    fmt.Println(data.Response) 
} 

错误输出。我不明白错误在哪里。请帮帮我。


回答

1

1-这里指定的字段是工作代码,尝试在The Go Playground

package main 

import (
    "encoding/json" 
    "fmt" 
) 

func main() { 
    var d *R 
    err := json.Unmarshal([]byte(str), &d) 
    if err != nil { 
     panic(err) 
    } 
    var data R2 
    data.Count = int(d.Response[0].(float64)) 

    for _, v := range d.Response[1:] {  
     bs, err := json.Marshal(v) 
     if err != nil { 
      panic(err) 
     } 
     var d1 *D 
     err = json.Unmarshal(bs, &d1) 
     if err != nil { 
      panic(err) 
     } 
     data.Response = append(data.Response, *d1) 
    } 
    fmt.Println(data)  
} 

type R struct { 
    Response []interface{} `json:"response"` 
} 

var str = ` { 
    "response": [ 
    777, 
    { 
     "id": 888, 
     "from_id": 999, 
     "to_id": 888, 
     "text": "hello" 
    }, 
     { 
     "id": 999, 
     "from_id": 888, 
     "to_id": 999, 
      "text": "goodbye" 
    } 
    ] 
}` 

type D struct { 
    Id  int `json:"id"` 
    FromId int `json:"from_id"` 
    ToId int `json:"to_id"` 
    Text string `json:"text"` 
} 
type R2 struct { 
    Count int 
    Response []D 
} 

输出:

{777 [{888 999 888 hello} {999 888 999 goodbye}]} 
+0

@topas:看到新的编辑 –

+1

谢谢,好男人;) – topas

+0

@topas:不客气。 –

0

您的回复json无效。您可以使用数组而不是结构与类型D.

0

我有一个不同方法:https://play.golang.org/p/9Xnxk7tVxE

您只需实现Unmarshaler接口并在方法UnmarshalJSON中添加逻辑即可。这是一个类似的解决方案,以另一种,但因为你没有做,在主要的或外部的方法,它更便携,它的小更强大的:)

package main 

import (
    "encoding/json" 
    "fmt" 
    "log" 
) 

var j = `{ 
    "response": [ 
    777, 
    { 
     "id": 888, 
     "from_id": 999, 
     "to_id": 888, 
     "text": "hello..." 
    }, 
    { 
     "id": 999, 
     "from_id": 888, 
     "to_id": 999, 
      "text": "goodbye..." 
    } 
    ] 
}` 

type D struct { 
    Id  int `json:"id"` 
    FromId int `json:"from_id"` 
    ToId int `json:"to_id"` 
    Text string `json:"text"` 
} 

type R struct { 
    Count int 
    Response []D 
} 

func (r *R) UnmarshalJSON(data []byte) error { 
    var values struct { 
     Resp []interface{} `json:"response"` 
    } 

    if err := json.Unmarshal(data, &values); err != nil { 
     return err 
    } 

    if len(values.Resp) < 1 { 
     return fmt.Errorf("empty response %v", values.Resp) 
    } 

    count, isNumber := values.Resp[0].(float64) 
    if !isNumber { 
     return fmt.Errorf("first element has to be a number, we got '%T'", values.Resp[0]) 
    } 
    r.Count = int(count) 

    for _, elem := range values.Resp[1:] { 
     de, err := json.Marshal(elem) 
     if err != nil { 
      return err 
     } 
     var d D 
     if err := json.Unmarshal(de, &d); err != nil { 
      return err 
     } 
     r.Response = append(r.Response, d) 
    } 
    return nil 
} 

func main() { 
    var data = new(R) 
    if err := json.Unmarshal([]byte(j), &data); err != nil { 
     log.Fatal(err) 
    } 
    fmt.Println(*data) 
}