Reputation:
I’ve multiple yaml files which need to be parsed and have exactly the same structure
schema: "1.0.0"
id: test
version: "1.2.3"
dependency :
- name: ui
type: runner
cwd: /ui
install:
- name: api
group: test
properties:
name: app
url: appUrl
- name: backend
type: mongoDb
path: be
install:
- name: db
type: mongo
provides:
- name: api
properties:
url: url
The schema section is mandatory for all the yaml which the app should get always
The dependency tag can contain 1..n entries with mandatory fields ,name, type, cwd
The dependency tag can (or not) contain
install
section withname
andproperties
which is mandatoryThe dependency tag can (or not) contain
provides
section withname
and which is mandatoryThe install can have properties and the provides also can have properties
I am using a yaml parser to parse the files but my question is how in Golang I can build struct that when I parse the doc it will automatically fill the main struct and will include the sub structs (such as dependency/ install sections )
I have tried something like
type main struct {
schema struct {
schema string
id int
version string
}
dependency struct {
name string
type string
cwd string
install struct {
name string
}
}
In the install section, it can be group or type or both and it can have also properties section, so I'm not sure how to build some generic /extendable struct which I use to parse the document (the document have close list of properties, what I put in the example describe the most options)
I use this lib to parse the doc
Upvotes: 0
Views: 7934
Reputation: 768
Your struct definition should be something like this
type Yaml struct {
Schema string
ID string
Version string
Dependency []Dependency
}
type Dependency struct {
Name string
Type string
CWD string
Install []Install
Provides []Provide
}
type Install struct {
Name string
Group string
Type string
Properties Properties
}
type Properties struct {
Name string
URL string
}
type Provide struct {
Name string
Properties Properties
}
Here is full sample code:
package main
import (
"fmt"
"io/ioutil"
"log"
"gopkg.in/yaml.v2"
)
var data = `
schema: "1.0.0"
id: test
version: "1.2.3"
dependency :
- name: ui
type: runner
cwd: /ui
install:
- name: api
group: test
properties:
name: app
url: appUrl
- name: backend
type: mongoDb
path: be
install:
- name: db
type: mongo
provides:
- name: api
properties:
url: url
`
type Yaml struct {
Schema string
ID string
Version string
Dependency []Dependency
}
type Dependency struct {
Name string
Type string
CWD string
Install []Install
Provides []Provide
}
type Install struct {
Name string
Group string
Type string
Properties Properties
}
type Properties struct {
Name string
URL string
}
type Provide struct {
Name string
Properties Properties
}
func main() {
y := Yaml{}
err := yaml.Unmarshal([]byte(data), &y)
if err != nil {
log.Fatalf("error: %v", err)
}
fmt.Printf("%+v\n", y)
}
Output
{Schema:1.0.0 ID:test Version:1.2.3 Dependency:[{Name:ui Type:runner CWD:/ui Install:[{Name:api Group:test Type: Properties:{Name:appURL:appUrl}}] Provides:[]} {Name:backend Type:mongoDb CWD: Install:[{Name:db Group: Type:mongo Properties:{Name: URL:}}] Provides:[{Name:api Properties:{Name: URL:url}}]}]}
If you want to read from a yaml file, in the main func just replace:
err := yaml.Unmarshal([]byte(data), &y)
with
yamlFile, err := ioutil.ReadFile("yaml_sample.yaml")
if err != nil {
log.Printf("yamlFile.Get err #%v ", err)
}
err = yaml.Unmarshal(yamlFile, &y)
Upvotes: 4