2016-09-29 44 views
1

我意識到這個問題是非常類似於其他人在stackoverflow,但我還沒有能夠模型的其他問題到我的用例。Unmarshal JSON與嵌套地圖的許多層

我有JSON,看起來像這樣(簡化爲這個職位)

{ 
    "somekey": "string", 
    "state": { 
    "groups": { 
     "host:host1": { 
     "status": "OK", 
     "morethings": "blah" 
     }, 
     "host:host2": { 
     "status": "Alert", 
     "morethings": "blah" 
     } 
    } 
    } 
} 

我試圖讓groups下的哈希值到一個數組,所以我可以遍歷並檢查主機的狀態。
基於這裏的一些其他職位的,我覺得我是在正確的軌道上與此example

package main 

import (
    "encoding/json" 
    "fmt" 
) 

const jsonStream = ` 
{ 
    "state": { 
    "groups": { 
     "host:i-b3a6cea5": { 
     "status": "OK", 
     "last_triggered_ts": null, 
     "last_nodata_ts": null, 
     "name": "host:i-b3a6cea5", 
     "last_notified_ts": null, 
     "last_resolved_ts": null 
     }, 
     "host:i-4d81ca7c": { 
     "status": "OK", 
     "last_triggered_ts": null, 
     "last_nodata_ts": null, 
     "name": "host:i-4d81ca7c", 
     "last_notified_ts": null, 
     "last_resolved_ts": null 
     }, 
     "host:i-a03a7758": { 
     "status": "Alert", 
     "triggering_value": { 
      "to_ts": 1475092440, 
      "value": 2, 
      "from_ts": 1475092380 
     }, 
     "last_triggered_ts": 1475092440, 
     "last_nodata_ts": null, 
     "name": "host:i-a03a7758", 
     "last_notified_ts": 1475092440, 
     "last_resolved_ts": null 
     } 
    } 
    } 
}` 

type hostDetails struct { 
    Status string `json:"status"` 
    Name string `json:"name"` 
} 

type GroupsData struct { 
    Groups map[string]hostDetails `json:"groups"` 
} 

type Data struct { 
    State map[string]GroupsData `json:"state"` 
} 

func main() { 
    var data Data 

    err := json.Unmarshal([]byte(jsonStream), &data) 
    if err != nil { 
     fmt.Println(err) 
    } 

    fmt.Println(data) 

} 

但我只用一個空的數據結構結束:

{map[groups:{map[]}]} 

要查看我甚至在正確的軌道上,我修改我的JSON,並拿出state密鑰,以便groups是在頂層。
當我這樣做,它填充數據結構如圖here

我掙扎理解爲什麼我可以處理1級的嵌套,但不是第二級?
我的穴居人大腦認爲我應該能夠重複使用這種模式,以達到我擁有的儘可能多的嵌套層次。
在這一點上,我一直在擺弄大部分時間,覺得我錯過了在我面前的東西,但看不到它。
任何指針將不勝感激如何處理額外的嵌套層。

回答

0

1 - 您可以通過刪除一個額外的級別:

var data map[string]GroupsData 

嘗試在The Go Playground

package main 

import (
    "encoding/json" 
    "fmt" 
) 

func main() { 
    var data map[string]GroupsData 
    err := json.Unmarshal([]byte(jsonStream), &data) 
    if err != nil { 
     fmt.Println(err) 
    }  
    fmt.Println(data)  
} 

type GroupsData struct { 
    Groups map[string]HostDetails `json:"groups"` 
} 

type HostDetails struct { 
    Status string `json:"status"` 
    Name string `json:"name"` 
} 

const jsonStream = ` 
{ 
    "state": { 
     "groups": { 
      "host:i-b3a6cea5": { 
       "status": "OK", 
       "last_triggered_ts": null, 
       "last_nodata_ts": null, 
       "name": "host:i-b3a6cea5", 
       "last_notified_ts": null, 
       "last_resolved_ts": null 
      }, 
      "host:i-4d81ca7c": { 
       "status": "OK", 
       "last_triggered_ts": null, 
       "last_nodata_ts": null, 
       "name": "host:i-4d81ca7c", 
       "last_notified_ts": null, 
       "last_resolved_ts": null 
      }, 
      "host:i-a03a7758": { 
       "status": "Alert", 
       "triggering_value": { 
        "to_ts": 1475092440, 
        "value": 2, 
        "from_ts": 1475092380 
       }, 
       "last_triggered_ts": 1475092440, 
       "last_nodata_ts": null, 
       "name": "host:i-a03a7758", 
       "last_notified_ts": 1475092440, 
       "last_resolved_ts": null 
      } 
     } 
    } 
}` 

輸出:

map[state:{map[host:i-b3a6cea5:{OK host:i-b3a6cea5} host:i-4d81ca7c:{OK host:i-4d81ca7c} host:i-a03a7758:{Alert host:i-a03a7758}]}] 

2 - 你可能使用:

type Data struct { 
    State GroupsData `json:"state"` 
} 

嘗試在The Go Playground

package main 

import (
    "encoding/json" 
    "fmt" 
) 

func main() { 
    var data Data  
    err := json.Unmarshal([]byte(jsonStream), &data) 
    if err != nil { 
     fmt.Println(err) 
    }  
    fmt.Println(data)  
} 

type Data struct { 
    State GroupsData `json:"state"` 
} 
type GroupsData struct { 
    Groups map[string]hostDetails `json:"groups"` 
} 

type hostDetails struct { 
    Status string `json:"status"` 
    Name string `json:"name"` 
} 

const jsonStream = ` 
{ 
    "state": { 
    "groups": { 
     "host:i-b3a6cea5": { 
     "status": "OK", 
     "last_triggered_ts": null, 
     "last_nodata_ts": null, 
     "name": "host:i-b3a6cea5", 
     "last_notified_ts": null, 
     "last_resolved_ts": null 
     }, 
     "host:i-4d81ca7c": { 
     "status": "OK", 
     "last_triggered_ts": null, 
     "last_nodata_ts": null, 
     "name": "host:i-4d81ca7c", 
     "last_notified_ts": null, 
     "last_resolved_ts": null 
     }, 
     "host:i-a03a7758": { 
     "status": "Alert", 
     "triggering_value": { 
      "to_ts": 1475092440, 
      "value": 2, 
      "from_ts": 1475092380 
     }, 
     "last_triggered_ts": 1475092440, 
     "last_nodata_ts": null, 
     "name": "host:i-a03a7758", 
     "last_notified_ts": 1475092440, 
     "last_resolved_ts": null 
     } 
    } 
    } 
}` 

輸出:

{{map[host:i-b3a6cea5:{OK host:i-b3a6cea5} host:i-4d81ca7c:{OK host:i-4d81ca7c} host:i-a03a7758:{Alert host:i-a03a7758}]}} 

code作品有一個額外的水平"state": {}在JSON數據:The Go Playground

0

你的錯誤是Data.State不應該是一個地圖。如果您將定義更改爲

type Data struct { 
    State GroupsData `json:"state"` 
} 

它的工作原理:https://play.golang.org/p/oRjSJMDzU8