在Golang中解组这个JSON

时间:2015-07-23 13:37:17

标签: json go

我自学了如何在Golang中使用JSON包。对于很多事情来说似乎很简单,但是我在解析从3D打印机检索到的一些JSON数据时遇到了麻烦。 JSON看起来像这样:

{
    "tasks": [
        {
            "class": "Task",
            "id": "5fee231a",
            "instances": {
                "28253266": {
                    "class": "StateInstance",
                    "id": "28253266",
                    "progress": 1,
                    "stateType": "Y-EdgeAvoiding"
                },
                "1d774b49": {
                    "class": "StateInstance",
                    "id": "1d774b49",
                    "progress": 1,
                    "stateType": "X-Calibration"
                },
            },
            "stateType": "StartingUp"
        }
    ]
}

(注意:还有更多"实例",但为了简洁,我没有包含它们,但它们都遵循这种模式,但使用不同的stateType)

基本上,打印机有一个正在执行的任务(在上面的例子中,任务的ID为5fee231a),在其中有子任务(例如,任务28253266)。

如果我使用此代码:

    var vals interface{}
    err = json.Unmarshal([]byte(myJSON), &vals)

    if err != nil {
        fmt.Println("Error:", err)
    }

    spew.Dump(&vals)

(使用github.com/davecgh/go-spew转储变量),然后我得到一些输出(注意:这不是整个输出,它是为了简洁而剪断的):)

(*map[string]interface {})(0xc0820068e0)((len=1) {
 (string) (len=5) "tasks": ([]interface {}) (len=1 cap=1) {
  (map[string]interface {}) (len=4) {
   (string) (len=5) "class": (string) (len=4) "Task",
   (string) (len=2) "id": (string) (len=8) "5fee231a",
   (string) (len=9) "instances": (map[string]interface {}) (len=13) {
    (string) (len=8) "bd65d028": (map[string]interface {}) (len=4) {
     (string) (len=5) "class": (string) (len=13) "StateInstance",
     (string) (len=2) "id": (string) (len=8) "bd65d028",
     (string) (len=8) "progress": (float64) 1,
     (string) (len=9) "stateType": (string) (len=17) "CenteringPosition"
    },
    (string) (len=8) "d1e225e7": (map[string]interface {}) (len=4) {
     (string) (len=2) "id": (string) (len=8) "d1e225e7",
     (string) (len=8) "progress": (float64) 1,
     (string) (len=9) "stateType": (string) (len=10) "TargetCold",
     (string) (len=5) "class": (string) (len=13) "StateInstance"
    },

这很好,但我希望能够获取给定实例的状态(例如,询问X-Calibration的进度,获得1作为回报。所以我创建了一些结构:

type Message struct {
    Tasks []struct {
        Class     string
        Id        string
        Instances []struct {
            Something []struct {
                Class     string
                Id        string
                StateType string
            }
        }
    }
}

Tasks被取消编组,但没有一个实例:

====================== Error: json: cannot unmarshal object into Go value of type []struct { Something struct { Class string; Id string; StateType string } }
(*buccaneer.Message)(0xc082002c40)({
 Tasks: ([]struct { Class string; Id string; Instances []struct { Something struct { Class string; Id string; StateType string } } }) (len=1 cap=4) {
  (struct { Class string; Id string; Instances []struct { Something struct { Class string; Id string; StateType string } } }) {
   Class: (string) (len=4) "Task",
   Id: (string) (len=8) "5fee231a",
   Instances: ([]struct { Something struct { Class string; Id string; StateType string } }) <nil>
  }
 }
})

并注意那里的something结构。我不知道该结构的名称是什么,因为实例具有唯一的名称(即每个&#34;子任务&#34;具有不同的ID)

非常感谢任何帮助:)

编辑:已更新以显示解组部分正常工作,但实例

除外

2 个答案:

答案 0 :(得分:3)

  • Instances需要是地图,因为它是一个对象。

  • 您内部不需要Something,因为它已经是map[string]struct{...}

  • (同样Id should really be ID,但这是一种风格挑剔。)

类型:

type Message struct {
    Tasks []struct {
        Class     string
        ID        string
        Instances map[string]struct {
            Class     string
            ID        string
            StateType string
        }
    }
}

游乐场:http://play.golang.org/p/r-wjaEiwP0

答案 1 :(得分:0)

除了Ainar-G发布的答案之外,我发现this website根据您粘贴的任何JSON为您生成结构。

当我从我的打印机粘贴JSON时,生成的代码完全混乱,并不像上面提供的答案那样紧凑和完整,但如果你有一些简单的JSON,你想快速转换对于一个结构,这可能对你有用。