如何在golang中轻松编辑JSON类型(例如Node.js)

时间:2018-08-03 08:28:48

标签: json node.js go hyperledger-fabric

我尝试将node.js代码转换为golang代码。

这是我的示例JSON。

{
  "result": {
    "birthInfo": {
      "birthYmd": "2018-07-25",
      "cattleNo": "cow001",
      "docType": "registerBirth",
      "lsTypeNm": "redbull",
      "monthDiff": "2018-07",
      "nationNm": "japan",
      "regType": "directly",
      "regYmd": "2018-07-25",
      "sexNm": "farm001"
    },
    "breed": {
      "dead": {
        "deadCd": "deadcd20180725",
        "deadYmd": "2018-07-25",
        "docType": "reportDeCattle"
      },
      "earTag": {
        "docType": "reattachEartag",
        "flatEartagNo": "eartag206015",
        "rfidNo": "rfid234234"
      }
    }
  }
}  

使用node.js时,很容易获得或访问json数据。

let cowbytes = await stub.getState("cow001");
var cowInfo = JSON.parse(cowbytes);

var eartag = {
  docType: 'reattachEartag',
  flatEartagNo: "eartag206015",
  rfidNo: "rfid234234",
};

if (cowInfo.breed) {
  cowInfo.breed['earTag'] = eartag;
} else {
  cowInfo.breed = {
    earTag: eartag
  };
}

await stub.putState(args[0], Buffer.from(JSON.stringify(cowInfo)));

这是我对node.js代码进行基准测试的golang代码。

cowbytes, _: = APIstub.GetState("cow001")
if cowbytes == nil {
  return shim.Error("Incorrect value. No cattle Info..")
}

var cowInfo map[string] interface {}
json.Unmarshal(cowbytes, & cowInfo)
eartag: = make(map[string] interface {})

eartag["docType"] = "reattachEartag"
eartag["flatEartagNo"] = string("eartag206015")
eartag["rfidNo"] = string("rfid234234")


_, exists: = cowInfo["breed"]
if exists {
  inputJSON,
  err: = json.Marshal(cowInfo["breed"])
  fmt.Println(err)
  out: = map[string] interface {} {}
  json.Unmarshal([] byte(inputJSON), & out)
  out["earTag"] = struct {
    EarTag map[string] interface {}
    `json:"earTag"`
  } {
    eartag,
  }
  cowInfo["breed"] = out

}
else {
  cowInfo["breed"] = struct {
    EarTag map[string] interface {}
    `json:"earTag"`
  } {
    eartag,
  }
}

cattleAsBytes, _: = json.Marshal(cowInfo)
APIstub.PutState(string("cow001"), cattleAsBytes)    

尽管我的golang文件可以正常工作,但我认为这不仅很难编写代码,而且性能也很差(重复的元组和非元组)。

如何在Golang中轻松控制JSON类型。

有人有主意吗?

2 个答案:

答案 0 :(得分:4)

通常必须在性能和简单性之间进行选择。

如果需要性能,则可以使用结构对JSON输入进行建模,然后可以在结构上使用selectors轻松获取/设置不同的部分,并且还可以免费获得Go的类型安全性。注意:有些库和在线服务会根据输入的JSON文本(例如https://mholt.github.io/json-to-go/)自动生成Go结构。

如果您选择简单,则可以使用允许轻松操纵“动态”对象(例如地图和切片)的第三方库。

其中一个是github.com/icza/dyno(披露:我是作者)。

使用dyno,该解决方案的简单性接近JavaScript。由于dyno在地图和切片上运行,因此对于某些任务可能会比较慢,但是对于您所要解决的简单任务,它可能甚至更快,因为它不使用反射(仅使用类型断言和类型切换)

比方说,标识符src保存您输入的JSON文本(可以是常量或变量),那么等效于您的Go代码为:

var cowInfo interface{}
if err := json.Unmarshal([]byte(src), &cowInfo); err != nil {
    panic(err)
}

eartag := map[string]string{
    "docType":      "reattachEartag",
    "flatEartagNo": "eartag206015",
    "rfidNo":       "rfid234234",
}

if breed, err := dyno.Get(cowInfo, "result", "breed"); err == nil {
    dyno.Set(breed, eartag, "earTag")
} else {
    dyno.Set(cowInfo, map[string]interface{}{"earTag": eartag}, "result", "breed")
}

enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", "  ")
if err := enc.Encode(cowInfo); err != nil {
    panic(err)
}

上面的代码解组输入的JSON,执行处理/修改,最后将结果编组到您的控制台上。

这是完整的应用程序:Go Playground。注意:您不能在Go Playground上运行它,因为它会导入github.com/icza/dyno(并且不允许在其中导入3rd lib),您必须在本地运行(获取dyno之后)。 / p>

答案 1 :(得分:0)

如果您的json结构是静态的,我建议定义适当的类型,例如:

type Result struct {
   BirthInfo struct {
       birthYmd string `json:"birthYmd"`
       // other fields go here
   } `json:"birthInfo"
   // ...
} `json:"result"`

然后解析一次并使用:

cowInfo.BirthInfo.CattleId