dou1908 2015-07-23 13:37
浏览 41
已采纳

在Golang中解组JSON

I'm teaching myself how to use the JSON package in Golang. It seems straightforward for a lot of things, but I'm having troubles parsing some JSON data I retrieved from my 3D printer. The JSON looks like this:

{
    "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"
        }
    ]
}

(NB: There's a few more "instances", but I didn't include them for brevity, but they all follow this pattern, but with a different stateType)

Basically, the printer has a task that it is doing (in the example above, the task has an ID of 5fee231a) and within it, sub-tasks (e.g. Task 28253266).

If I use this code:

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

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

    spew.Dump(&vals)

(using github.com/davecgh/go-spew to dump the variable), then I get some output (NB: This isn't the whole output, it's snipped for brevity :)):

(*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"
    },

This is nice, but I'd like to be be able to grab the status of a given instance (e.g. ask for the progress of X-Calibration, get 1 in return). So I created some structs:

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

Tasks gets unmarshalled, but none of the instances:

====================== 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>
  }
 }
})

And note the something struct in there. I don't know what to name that struct, as the instances have unique names (i.e. each "sub-task" has a different ID)

Any help is much appreciated :)

EDIT: Updated to show that unmarshalling is partially working, except for the Instances

  • 写回答

2条回答 默认 最新

  • dou70260 2015-07-23 14:10
    关注
    • Instances needs to be a map, because it's an object.

    • You don't need Something inside of it, since it's already a map[string]struct{...}.

    • (Also Id should really be ID, but that's a stylistic nitpick.)

    The type:

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

    Playground: http://play.golang.org/p/r-wjaEiwP0.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 请问如何在openpcdet上对KITTI数据集的测试集进行结果评估?
  • ¥15 powerbuilder中的datawindow数据整合到新的DataWindow
  • ¥20 有人知道这种图怎么画吗?
  • ¥15 pyqt6如何引用qrc文件加载里面的的资源
  • ¥15 安卓JNI项目使用lua上的问题
  • ¥20 RL+GNN解决人员排班问题时梯度消失
  • ¥60 要数控稳压电源测试数据
  • ¥15 能帮我写下这个编程吗
  • ¥15 ikuai客户端l2tp协议链接报终止15信号和无法将p.p.p6转换为我的l2tp线路
  • ¥15 phython读取excel表格报错 ^7个 SyntaxError: invalid syntax 语句报错