2020年11月7日 星期六

[ 文章收集 ] Parsing JSON files With Golang

 Source From Here

Preface
Welcome all, in this tutorial, we are going to be taking a look at how you can read in JSON files, or JSON HTTP responses and parse them to your hearts desire.

JSON or Javascript Object Notation as it is short for, is a standard format for sending and receiving information. We could represent the same information with either XML or JSON, but JSON provides one advantage in the fact it is far more compact and in my personal experience, more readable.

JSON is now the most popular data format available and you’ll find that most RESTful APIs provide JSON responses when you try to interface with them. Thus being able to work with it and parse it in Go is incredibly useful!

The Encoding/Json Package
So, to get us started, we’ll be leveraging the encoding/json standard library package in order to get us up and running. I highly recommend you check out the official documentation for this here: Encoding/Json. Let’s start with a really simple Go program as our base, we’ll build this out to showcase how to work with various different examples. Create a new file called main.go:
main.go
  1. package main  
  2.   
  3. import (  
  4.     "fmt"  
  5. )  
  6.   
  7. func main() {  
  8.     fmt.Println("Hello World")  
  9. }  
And we can run this with a simple go run main.go call. This should return a simple Hello World.

Reading and Parsing a JSON File
Let’s try and read in a simple JSON file and then parse it. For the purpose of this tutorial we’ll be parsing the following json within our file. Copy this and save it into a users.json file within the same directory as your main.go file:
- user.json
  1. {  
  2.   "users": [  
  3.     {  
  4.       "name""Elliot",  
  5.       "type""Reader",  
  6.       "age"23,  
  7.       "social": {  
  8.         "facebook""https://facebook.com",  
  9.         "twitter""https://twitter.com"  
  10.       }  
  11.     },  
  12.     {  
  13.       "name""Fraser",  
  14.       "type""Author",  
  15.       "age"17,  
  16.       "social": {  
  17.         "facebook""https://facebook.com",  
  18.         "twitter""https://twitter.com"  
  19.       }  
  20.     }  
  21.   ]  
  22. }  
This should be complex enough to test our skills and should allow us to transfer our skills to real world examples fairly easily.

Reading the JSON File
We’ll be using the os package in order to open up our users.json file from our filesystem. Once we have opened the file, we’ll defer the closing of the file till the end of the function so that we can work with the data inside of it:
  1. // Open our jsonFile  
  2. jsonFile, err := os.Open("users.json")  
  3. // if we os.Open returns an error then handle it  
  4. if err != nil {  
  5.     fmt.Println(err)  
  6. }  
  7. fmt.Println("Successfully Opened users.json")  
  8. // defer the closing of our jsonFile so that we can parse it later on  
  9. defer jsonFile.Close()  
Parsing with Structs
We have a few options when it comes to parsing the JSON that is contained within our users.json file. We could either unmarshal the JSON using a set of predefined structs, or we could unmarshal the JSON using a map[string]interface{} to parse our JSON into strings mapped against arbitrary data types.

If you know the structure that you are expecting then I would recommend going down the verbose route and defining your structs like so:
main.go
  1. package main  
  2.   
  3. import (  
  4.     …  
  5.     // import our encoding/json package  
  6.     “encoding/json”  
  7.     …  
  8. )  
  9.   
  10. // Users struct which contains  
  11. // an array of users  
  12. type Users struct {  
  13.     Users []User `json:"users"`  
  14. }  
  15.   
  16. // User struct which contains a name  
  17. // a type and a list of social links  
  18. type User struct {  
  19.     Name   string `json:"name"`  
  20.     Type   string `json:"type"`  
  21.     Age    int    `json:"Age"`  
  22.     Social Social `json:"social"`  
  23. }  
  24.   
  25. // Social struct which contains a  
  26. // list of links  
  27. type Social struct {  
  28.     Facebook string `json:"facebook"`  
  29.     Twitter  string `json:"twitter"`  
  30. }  
Once we have these in place, we can use them to unmarshal our JSON.

Unmarshalling our JSON
Once we’ve used the os.Open function to read our file into memory, we then have to convert it to a byte array using ioutil.ReadAll. Once it’s in a byte array we can pass it to our json.Unmarshal() method:
  1. // read our opened jsonFile as a byte array.  
  2. byteValue, _ := ioutil.ReadAll(jsonFile)  
  3.   
  4. // we initialize our Users array  
  5. var users Users  
  6.   
  7. // we unmarshal our byteArray which contains our  
  8. // jsonFile's content into 'users' which we defined above  
  9. json.Unmarshal(byteValue, &users)  
  10.   
  11. // we iterate through every user within our users array and  
  12. // print out the user Type, their name, and their facebook url  
  13. // as just an example  
  14. for i := 0; i < len(users.Users); i++ {  
  15.     fmt.Println("User Type: " + users.Users[i].Type)  
  16.     fmt.Println("User Age: " + strconv.Itoa(users.Users[i].Age))  
  17.     fmt.Println("User Name: " + users.Users[i].Name)  
  18.     fmt.Println("Facebook Url: " + users.Users[i].Social.Facebook)  
  19. }  
Working with Unstructured Data
Sometimes, going through the process of creating structs for everything can be somewhat time consuming and overly verbose for the problems you are trying to solve. In this instance, we can use standard interfaces{} in order to read in any JSON data:
  1. package main  
  2.   
  3. import (  
  4.     "encoding/json"  
  5.     "fmt"  
  6.     "io/ioutil"  
  7.     "os"  
  8. )  
  9.   
  10. func main() {  
  11.   
  12.     // Open our jsonFile  
  13.     jsonFile, err := os.Open("users.json")  
  14.     // if we os.Open returns an error then handle it  
  15.     if err != nil {  
  16.         fmt.Println(err)  
  17.     }  
  18.     fmt.Println("Successfully Opened users.json")  
  19.     // defer the closing of our jsonFile so that we can parse it later on  
  20.     defer jsonFile.Close()  
  21.   
  22.     byteValue, _ := ioutil.ReadAll(jsonFile)  
  23.   
  24.     var result map[string]interface{}  
  25.     json.Unmarshal([]byte(byteValue), &result)  
  26.   
  27.     fmt.Println(result["users"])  
  28.   
  29. }  
You can see in the above code, we’ve managed to open our users.json and parse the JSON much like we would normally do in other programming languages such as Python or JavaScript. When we run this, we should see that printing result["users"] results in a map being outputted to the console:
$ go run main.go
Successfully opened users.json
[map[type:Reader age:23 social:map[facebook:https://facebook.com twitter:https://twitter.com] name:Elliot] map[name:Frasertype:Author age:17 social:map[facebook:https://facebook.com twitter:https://twitter.com]]]

If we wanted to traverse further down the tree, we could do that just as we normally would traverse down a map structure within Go, without having to define the struct types.

Full Implementation
Below you’ll find the full implementation of this tutorial:
main.go
  1. package main  
  2.   
  3. import (  
  4.     "encoding/json"  
  5.     "fmt"  
  6.     "io/ioutil"  
  7.     "os"  
  8.     "strconv"  
  9. )  
  10.   
  11. // Users struct which contains  
  12. // an array of users  
  13. type Users struct {  
  14.     Users []User `json:"users"`  
  15. }  
  16.   
  17. // User struct which contains a name  
  18. // a type and a list of social links  
  19. type User struct {  
  20.     Name   string `json:"name"`  
  21.     Type   string `json:"type"`  
  22.     Age    int    `json:"Age"`  
  23.     Social Social `json:"social"`  
  24. }  
  25.   
  26. // Social struct which contains a  
  27. // list of links  
  28. type Social struct {  
  29.     Facebook string `json:"facebook"`  
  30.     Twitter  string `json:"twitter"`  
  31. }  
  32.   
  33. func main() {  
  34.     // Open our jsonFile  
  35.     jsonFile, err := os.Open("users.json")  
  36.     // if we os.Open returns an error then handle it  
  37.     if err != nil {  
  38.         fmt.Println(err)  
  39.     }  
  40.   
  41.     fmt.Println("Successfully Opened users.json")  
  42.     // defer the closing of our jsonFile so that we can parse it later on  
  43.     defer jsonFile.Close()  
  44.   
  45.     // read our opened xmlFile as a byte array.  
  46.     byteValue, _ := ioutil.ReadAll(jsonFile)  
  47.   
  48.     // we initialize our Users array  
  49.     var users Users  
  50.   
  51.     // we unmarshal our byteArray which contains our  
  52.     // jsonFile's content into 'users' which we defined above  
  53.     json.Unmarshal(byteValue, &users)  
  54.   
  55.     // we iterate through every user within our users array and  
  56.     // print out the user Type, their name, and their facebook url  
  57.     // as just an example  
  58.     for i := 0; i < len(users.Users); i++ {  
  59.         fmt.Println("User Type: " + users.Users[i].Type)  
  60.         fmt.Println("User Age: " + strconv.Itoa(users.Users[i].Age))  
  61.         fmt.Println("User Name: " + users.Users[i].Name)  
  62.         fmt.Println("Facebook Url: " + users.Users[i].Social.Facebook)  
  63.     }  
  64.   
  65. }  
Further Reading
Creating a RESTful API with Go
Creating a Simple Web Server with Go

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...