在golang中构造复杂的JSON解析

时间:2017-12-12 07:29:22

标签: json parsing go

我有一个有效的JSON,我不知道如何解析json.Unmarshal(golang):

{
   "method": "notice",
   "params": [0, [{
           "previous": "12345",
           "timestamp": "2017-12-12T05:49:09",
           "witness": "12345",
           "transaction_merkle_root": "ffff",
           "extensions": [],
           "witness_signature": "12345"
   }]]
}

我所能做的就是:

type MyJSON struct {
    Method string        `json:"method"`
    Params []interface{} `json:"params"`
}

如果有人帮我编写正确的MyJSON类型来通过golang的json.Unmarshal来解析所有其他字段,我将非常感激。这对我来说太复杂了:(

2 个答案:

答案 0 :(得分:3)

我认为params取决于method。如果是这样,首先将顶层解码为具有方法名称和json.RawMessage的结构,以将参数收集为JSON文本。

var call struct {
    Method string
    Params json.RawMessage
}
if err := json.Unmarshal(data, &call); err != nil {
    log.Fatal(err)
}

为每个参数声明变量。此代码取决于方法。

    var param0 int
    var param1 []struct {
        Previous                string
        Timestamp               string
        Witness                 string
        Transaction_merkle_root string
        Extensions              []interface{}
        Witness_signature       string
    }

使用指向这些变量的指针创建参数列表。

    params := []interface{}{&param0, &param1}

现在将JSON解组为params。这将设置变量param0和param1:

    if err := json.Unmarshal(call.Params, &params); err != nil {
        log.Fatal(err)
    }

重复其他方法。

Here's the runnable code on the playground

如果您只需要处理“通知”方法,则可以简化此操作。在这种情况下,您可以直接解码参数而无需RawMessage步骤。

var param0 int
var param1 []struct {
    Previous                string
    Timestamp               string
    Witness                 string
    Transaction_merkle_root string
    Extensions              []interface{}
    Witness_signature       string
}
call := struct {
    Method string
    Params []interface{}
}{
    Params: []interface{}{&param0, &param1},
}

if err := json.Unmarshal(data, &call); err != nil {
    log.Fatal(err)
}

Here's runnable code for the simple case

答案 1 :(得分:0)

尝试使用fastjson。它能够解析和查询任意JSON,而无需定义其他结构,也无需生成代码:

var p fastjson.Parser
v, err := p.Parse(data)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("method=%s", v.GetStringBytes("method"))

// GetStringBytes accepts a path of keys to extract json value.
// Array indexes must be passed as decimal strings.
fmt.Printf("timestamp=%s", v.GetStringBytes("params", "1", "0", "timestamp"))