How does golang modify the json file content method example

  • 2020-06-19 10:30:58
  • OfStack

Use 1 example to show how golang accesses and modifies json files; There are three main steps:

Read the json string from the file Converts the json string to an golang object Iterate through or modify the json value Write to file

Assume that the user input json string is:


{
 "user": {
  "mspid": "admin",
  "email": "admin@domain.com"
 }, 
 "nodes": [
  {  
   "name": "node1",
   "location": "node1.domain.com:8080"
  }, 
  {  
   "name": "node2",
   "location": "node2.domain.com:8080"
  }  
 ]
}

Our goal is to replace the location fields of node1 and node2.

The following code


import (
  "fmt"
  "io/ioutil"
  "encoding/json"
)

func HandleJson(jsonFile string, outFile string) error {
  // Read json buffer from jsonFile
  byteValue, err := ioutil.ReadFile(jsonFile)
  if err != nil {
    return err
  }

  // We have known the outer json object is a map, so we define result as map.
  // otherwise, result could be defined as slice if outer is an array
  var result map[string]interface{}
  err = json.Unmarshal(byteValue, &result)
  if err != nil {
    return err
  }

  // handle peers
  nodes:= result["nodes"].([]interface{})
  for _, node:= range node{
    m := node.(map[string]interface{})
    if name, exists := m["name"]; exists {
      if name == "node1" {
        m["location"] = "new-value1"
      } else if name == "node2" {
        m["location"] = "new-value2"
      }
    }
  }

  // Convert golang object back to byte
  byteValue, err = json.Marshal(result)
  if err != nil {
    return err
  }

  // Write back to file
  err = ioutil.WriteFile(outFile, byteValue, 0644)
  return err
}

This place USES the interface{} data type of golang, and then converts interface{} to the real data type.

This function can be extended to dynamically parse any type, as long as all types are defined as interface{}, and then the dynamic type detection can be used to know the type of each specific element, and finally achieve the function of type jq, access and modify the json file.


var x interface{} = ...

switch x.(type) {
  case nil:
    fmt.Println("x is nil")
  case int: 
    fmt.Println("x is int")
  case bool :
    fmt.Println("x is bool")
  case string:
    fmt.Println("x is string")
  case []interface{}:
    fmt.Println("x is slice")
  case map[string]interface{}:
    fmt.Println("x is map")
  default:
    fmt.Println("type unknown")
  }  
}

PS: It is said that ES33en-ES34en is the fastest golang package for data processing in json format (6 times faster than the official json package). It seems to be open source by Didi Team, and it is very convenient to use. Those who are interested can learn


package main

import "github.com/json-iterator/go"

type User struct {
  Name string
  Age int8
}

func main() {
  user := User{
      Name: "tanggu",
      Age: 18,
    }
    var jsoniter = jsoniter.ConfigCompatibleWithStandardLibrary
    //  serialization 
    data, err := jsoniter.Marshal(&user)
    if err != nil {
      log.Fatal(err)
    }
    fmt.Println(string(data))

    //  deserialization 
    var people User
    err = jsoniter.Unmarshal(data, &people)
    if err != nil {
      log.Fatal(err)
    }
    fmt.Println(people)
}

Related articles: