【问题标题】:Struct to complex JSON parsing in golanggolang中结构复杂的JSON解析
【发布时间】:2017-12-12 07:29:21
【问题描述】:

我有一个有效的 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 解析所有其他字段,我将非常感激。这对我来说太复杂了:(

【问题讨论】:

    标签: json parsing go


    【解决方案1】:

    我假设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 解组为参数。这将设置变量 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.

    【讨论】:

      【解决方案2】:

      尝试使用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"))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-24
        • 2018-04-11
        • 1970-01-01
        相关资源
        最近更新 更多