我有这种类型的JSON结构
{
"iptables" : false,
"dns" : ["8.8.8.8","8.8.4.4"]
}
在解开JSON对象之上的过程中,我需要保留密钥,例如{
"<server>": {
"<guest>": {
"<service>": {
"<part>": {
"num": "<number>",
"type": "<type>",
"timestamp": "2016-02-01T12:53:12Z"
}
}
}
}
}
,server
等。我想到了struct下面但是我无法在JSON对象上解组,因为在解组时键会丢失。
guest
有没有办法将JSON对象上面解组成struct保持密钥完整。
编辑:
type Section struct {
Bytes int
Files int
Timestamp time.Time
}
type Report struct {
Server string
Guest string
Service string
Part string
Details Section
}
内的文字正在发生变化。这就是为什么我需要在松散之后保留它以便我可以进一步研究它。
答案 0 :(得分:1)
对于上面的JSON,这个结构可以正常工作。
type Report struct {
Server struct {
Guest struct {
Service struct {
Part struct {
Num string `json:"num"`
Type string `json:"type"`
Timestamp time.Time `json:"timestamp"`
} `json:"<part>"`
} `json:"<service>"`
} `json:"<guest>"`
} `json:"<server>"`
}
答案 1 :(得分:1)
1-在The Go Playground上尝试:
package main
import (
"encoding/json"
"fmt"
"time"
)
func main() {
s := `{
"<server1>": {
"<guest2>": {
"<service3>": {
"<part4>": {
"num": 12,
"type": 14,
"timestamp": "2016-02-01T12:53:12Z"
}
}
}
}
}`
var data map[string]map[string]map[string]map[string]Section
err := json.Unmarshal([]byte(s), &data)
if err != nil {
fmt.Println(err)
}
fmt.Println(data)
}
type Section struct {
Bytes int `json:"num"`
Files int `json:"type"`
Timestamp time.Time `json:"timestamp"`
}
type Report struct {
Server string
Guest string
Service string
Part string
Details Section
}
输出:
map[<server1>:map[<guest2>:map[<service3>:map[<part4>:{12 14 2016-02-01 12:53:12 +0000 UTC}]]]]
2-转换为Report struct
,在The Go Playground上尝试:
package main
import (
"encoding/json"
"fmt"
"time"
)
func main() {
s := `{
"<server1>": {
"<guest2>": {
"<service3>": {
"<part4>": {
"num": 12,
"type": 14,
"timestamp": "2016-02-01T12:53:12Z"
}
}
}
}
}`
var data map[string]map[string]map[string]map[string]Section
err := json.Unmarshal([]byte(s), &data)
if err != nil {
fmt.Println(err)
}
r := Report{}
for k, v := range data {
r.Server = k
for k2, v2 := range v {
r.Guest = k2
for k3, v3 := range v2 {
r.Service = k3
for k4, v4 := range v3 {
r.Part = k4
r.Details = v4
}
}
}
}
fmt.Println(r)
}
type Section struct {
Bytes int `json:"num"`
Files int `json:"type"`
Timestamp time.Time `json:"timestamp"`
}
type Report struct {
Server string
Guest string
Service string
Part string
Details Section
}
输出:
{<server1> <guest2> <service3> <part4> {12 14 2016-02-01 12:53:12 +0000 UTC}}
答案 2 :(得分:1)
我写过a library可以让这更容易使用。可以针对您的JSON格式解组Reports
:
package main
import (
"time"
"github.com/go-restit/lzjson"
)
type Section struct {
Bytes int `json:"num"`
Files int `json:"type"`
Timestamp time.Time `json:"timestamp"`
}
type Report struct {
Server string
Guest string
Service string
Part string
Details Section
}
type Reports []Report
func (reports *Reports) UnmarshalJSON(content []byte) (err error) {
root := lzjson.NewNode()
if err = json.Unmarshal(content, &root); err != nil {
return
}
// reset the slice of reports
*reports = make([]Report, 0, 10)
for _, serverName := range root.GetKeys() {
server := root.Get(serverName)
if err = server.Error(); err != nil {
return
}
for _, guestName := range server.GetKeys() {
guest := server.Get(guestName)
if err = guest.Error(); err != nil {
return
}
for _, serviceName := range guest.GetKeys() {
service := guest.Get(serviceName)
if err = service.Error(); err != nil {
return
}
for _, partName := range service.GetKeys() {
part := service.Get(partName)
if err = part.Error(); err != nil {
return
}
var report Report
timestamp, _ := time.Parse("2006-01-02T15:04:05Z", part.Get("timestamp").String())
report.Server = serverName
report.Guest = guestName
report.Service = serviceName
report.Part = partName
report.Details = Section{
Bytes: part.Get("num").Int(),
Files: part.Get("type").Int(),
Timestamp: timestamp,
}
*reports = append(*reports, report)
}
}
}
}
return
}
您现在可以执行此操作:
package main
import (
"encoding/json"
"log"
)
func main() {
raw := `
{
"<server 1>": {
"<guest>": {
"<service>": {
"<part>": {
"num": "<number>",
"type": "<type>",
"timestamp": "2016-02-01T12:53:12Z"
}
}
}
},
"<server 2>": {
"<guest>": {
"<service>": {
"<part>": {
"num": "<number>",
"type": "<type>",
"timestamp": "2016-02-01T12:53:12Z"
}
}
}
}
}`
var reports Reports
err := json.Unmarshal([]byte(raw), &reports)
if err != nil {
log.Fatalf("error reading reports: %s", err.Error())
}
log.Printf("Reports: %#v", reports)
}