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 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分