Master Go: Parse and Generate YAML, JSON, and XML Files

This tutorial demonstrates how to use Go's standard and third‑party libraries to parse and generate YAML, JSON, and XML files, covering data structures, unmarshalling, marshalling, handling maps, and producing readable output with code examples.

Ops Development Stories
Ops Development Stories
Ops Development Stories
Master Go: Parse and Generate YAML, JSON, and XML Files

Parse and Generate YAML Files

YAML is a human‑readable data‑serialization format often used for configuration files. In Go we use the gopkg.in/yaml.v3 package to work with YAML data.

go get gopkg.in/yaml.v3

Parse YAML

func Unmarshal(in []byte, out interface{}) (err error)

We define a Users struct that matches the YAML schema and read test.yaml:

type Users struct {
    Name    string   `yaml:"name"`
    Age     int8    `yaml:"age"`
    Address string   `yaml:"address"`
    Hobby   []string `yaml:"hobby"`
}

func main() {
    file, err := ioutil.ReadFile("test.yaml")
    if err != nil { log.Fatal(err) }
    var data [7]Users
    err = yaml.Unmarshal(file, &data)
    if err != nil { log.Fatal(err) }
    for _, v := range data {
        fmt.Println(v)
    }
}

Running the program prints each user record.

Generate YAML

func Marshal(in interface{}) (out []byte, err error)

We create several Users values, marshal them with yaml.Marshal, and write the result to test.yaml:

type Users struct {
    Name    string   `yaml:"name"`
    Age     int8    `yaml:"age"`
    Address string   `yaml:"address"`
    Hobby   []string `yaml:"hobby"`
}

func main() {
    wanger := Users{Name: "wanger", Age: 24, Address: "beijing", Hobby: []string{"literature", "social"}}
    // ... other users omitted for brevity
    userlist := []Users{wanger, /* other users */}
    yamlData, err := yaml.Marshal(&userlist)
    if err != nil { fmt.Printf("Error while Marshaling. %v", err) }
    ioutil.WriteFile("test.yaml", yamlData, 0644)
}

The generated YAML looks like:

- name: wanger
  age: 24
  address: beijing
  hobby:
    - literature
    - social
- name: 冬哥
  age: 30
  address: chengdu
  hobby:
    - basketball
    - guitar
... (other entries omitted)

Parse and Generate JSON Files

Go's encoding/json package provides Unmarshal and Marshal functions for JSON handling.

Read and Parse JSON

func Unmarshal(data []byte, v interface{}) error

We define structs that map to the JSON structure and read user.json:

type Users struct {
    Users []User `json:"users"`
}

type User struct {
    Name    string `json:"name"`
    Address string `json:"address"`
    Age     int    `json:"Age"`
    Social  Social `json:"social"`
}

type Social struct {
    Mobile string `json:"mobile"`
    Email  string `json:"email"`
}

func main() {
    jsonFile, err := os.Open("user.json")
    if err != nil { fmt.Println(err) }
    defer jsonFile.Close()
    byteValue, _ := ioutil.ReadAll(jsonFile)
    var users Users
    json.Unmarshal(byteValue, &users)
    for _, u := range users.Users {
        fmt.Println("User Type:", u.Address)
        fmt.Println("User Age:", u.Age)
        fmt.Println("User Name:", u.Name)
        fmt.Println("User Email:", u.Social.Email)
    }
}

When the JSON structure is unknown we can decode into map[string]interface{}:

var result map[string]interface{}
err = json.Unmarshal(byteValue, &result)
fmt.Printf("%+v
", result)

Generate JSON

func Marshal(v interface{}) ([]byte, error)

We build a slice of User values and marshal them with json.Marshal or json.MarshalIndent for pretty output:

func main() {
    wanger := User{Name: "wanger", Address: "beijing", Age: 24, Social: Social{Email: "[email protected]", Mobile: "111111111111"}}
    // ... other users omitted for brevity
    result := Users{Users: []User{wanger, /* other users */}}
    byteArray, err := json.MarshalIndent(result, "", "  ")
    if err != nil { fmt.Println(err) }
    fmt.Println(string(byteArray))
    ioutil.WriteFile("user.json", byteArray, 0644)
}

The pretty‑printed JSON output is structured with an array under the users key.

Parse and Generate XML Files

Go's encoding/xml package works similarly to JSON. XML attributes are handled with the ,attr tag option.

Parse XML

func Unmarshal(data []byte, v interface{}) error

Sample user.xml defines users with an address attribute. Corresponding structs use the `xml:"address,attr"` tag.

type Users struct {
    XMLName xml.Name `xml:"users"`
    Users   []User   `xml:"user"`
}

type User struct {
    XMLName xml.Name `xml:"user"`
    Address string   `xml:"address,attr"`
    Name    string   `xml:"name"`
    Social  Social   `xml:"social"`
}

type Social struct {
    XMLName xml.Name `xml:"social"`
    Mobile  string   `xml:"mobile"`
    Email   string   `xml:"email"`
}

func main() {
    xmlFile, err := os.Open("users.xml")
    if err != nil { fmt.Println(err) }
    defer xmlFile.Close()
    byteValue, _ := ioutil.ReadAll(xmlFile)
    var users Users
    xml.Unmarshal(byteValue, &users)
    for _, u := range users.Users {
        fmt.Println("User Address:", u.Address)
        fmt.Println("User Name:", u.Name)
        fmt.Println("Facebook Url:", u.Social.Email)
    }
}
To correctly unmarshal XML, all struct fields must be exported (capitalized).

Generate XML

func Marshal(v interface{}) ([]byte, error)
func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)

We create User values, assemble them into a Users container, and marshal with xml.MarshalIndent for readable formatting:

func main() {
    wanger := User{Address: "beijing", Name: "wanger", Age: 24, Social: Social{Email: "[email protected]", Mobile: "111111111111"}}
    // ... other users omitted for brevity
    v := &Users{Users: []User{wanger, /* other users */}}
    result, err := xml.MarshalIndent(v, "  ", "    ")
    if err != nil { fmt.Printf("error: %v
", err) }
    fmt.Println(string(result))
    ioutil.WriteFile("users.xml", result, 0644)
}

The resulting XML is nicely indented and includes the address attribute for each user element.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Backend DevelopmentGoJSONXMLYAMLdata serialization
Ops Development Stories
Written by

Ops Development Stories

Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.