2015-02-23 41 views
7

Tôi đang cố gắng phân tích cú pháp tệp yaml bằng Go. Thật không may tôi không thể tìm ra cách. Các tập tin yaml tôi có là thế này:Đi phân tích cú pháp tệp yaml

--- 
firewall_network_rules: 
    rule1: 
    src:  blablabla-host 
    dst:  blabla-hostname 
... 

tôi có mã Go này, nhưng nó không hoạt động:

package main 

import (
    "fmt" 
    "io/ioutil" 
    "path/filepath" 

    "gopkg.in/yaml.v2" 
) 

type Config struct { 
    Firewall_network_rules map[string][]string 
} 

func main() { 
    filename, _ := filepath.Abs("./fruits.yml") 
    yamlFile, err := ioutil.ReadFile(filename) 

    if err != nil { 
     panic(err) 
    } 

    var config Config 

    err = yaml.Unmarshal(yamlFile, &config) 
    if err != nil { 
     panic(err) 
    } 

    fmt.Printf("Value: %#v\n", config.Firewall_network_rules) 
} 

Khi tôi chạy này, tôi nhận được một lỗi. Tôi nghĩ rằng đó là bởi vì tôi đã không tạo ra một cấu trúc cho src và dst khóa/giá trị. FYI: khi tôi thay đổi nó thành một danh sách, nó hoạt động.

đang Vậy trên phân tích này:

--- 
firewall_network_rules: 
    rule1: 
    - value1 
    - value2 
... 

Trả lời

5

Vâng, tôi nghĩ rằng tôi đã figured it out bởi bản thân mình. Đoạn mã sau hoạt động tốt. Bất kỳ đề xuất/cải tiến nào?

package main 

import (
    "fmt" 
    "io/ioutil" 
    "path/filepath" 

    "gopkg.in/yaml.v2" 
) 

type Config struct { 
    Firewall_network_rules map[string]Options 
} 

type Options struct { 
    Src string 
    Dst string 
} 

func main() { 
    filename, _ := filepath.Abs("./fruits.yml") 
    yamlFile, err := ioutil.ReadFile(filename) 

    if err != nil { 
     panic(err) 
    } 

    var config Config 

    err = yaml.Unmarshal(yamlFile, &config) 
    if err != nil { 
     panic(err) 
    } 

    fmt.Printf("Value: %#v\n", config.Firewall_network_rules) 
} 
+1

Thử nhiều thành ngữ 'FirewallNetworkRules' và thêm một thẻ struct để nắm bắt những định dạng YAML - ví dụ '' yaml: "firewall_network_rules" '' Xem tại đây để biết các tài liệu về cách sử dụng thẻ struct trong thư viện YAML: http://godoc.org/gopkg.in/yaml.v2#Marshal – elithrar

+0

Cảm ơn bạn đã đề xuất, nó thực sự làm rõ mã của tôi. –

3

Tại sao không tổ chức tệp yaml của bạn như dưới đây nếu bạn không quan tâm đến tên quy tắc?

--- 
firewall_network_rules: 
    - 
    name:  rule1 
    src:  blablabla-host 
    dst:  blabla-hostname 
    - 
    name:  rule2 
    src:  bla-host 
    dst:  bla-hostname 

Vì vậy, các mã sẽ được như thế này, nó là sạch và mở rộng:

type Rule struct { 
    Name string `yaml:"name"` 
    Src string `yaml:"src"` 
    Dst string `yaml:"dst"` 
} 

type Config struct { 
    FirewallNetworkRules []Rule `yaml:"firewall_network_rules"` 
} 
4

Nếu bạn đang làm việc với google đám mây hoặc kubernetes cụ thể hơn và muốn phân tích một service.yaml như thế này :

apiVersion: v1 
kind: Service 
metadata: 
    name: myName 
    namespace: default 
    labels: 
    router.deis.io/routable: "true" 
    annotations: 
    router.deis.io/domains: "" 
spec: 
    type: NodePort 
    selector: 
    app: myName 
    ports: 
    - name: http 
     port: 80 
     targetPort: 80 
    - name: https 
     port: 443 
     targetPort: 443 

Cung cấp ví dụ về thế giới thực để bạn nắm được cách lồng có thể viết.

type Service struct { 
    APIVersion string `yaml:"apiVersion"` 
    Kind  string `yaml:"kind"` 
    Metadata struct { 
     Name  string `yaml:"name"` 
     Namespace string `yaml:"namespace"` 
     Labels struct { 
      RouterDeisIoRoutable string `yaml:"router.deis.io/routable"` 
     } `yaml:"labels"` 
     Annotations struct { 
      RouterDeisIoDomains string `yaml:"router.deis.io/domains"` 
     } `yaml:"annotations"` 
    } `yaml:"metadata"` 
    Spec struct { 
     Type  string `yaml:"type"` 
     Selector struct { 
      App string `yaml:"app"` 
     } `yaml:"selector"` 
     Ports []struct { 
      Name  string `yaml:"name"` 
      Port  int `yaml:"port"` 
      TargetPort int `yaml:"targetPort"` 
      NodePort int `yaml:"nodePort,omitempty"` 
     } `yaml:"ports"` 
    } `yaml:"spec"` 
} 

Có một dịch vụ thuận tiện gọi json-to-go https://mholt.github.io/json-to-go/ mà chuyển đổi json đi cấu trúc, chỉ cần chuyển đổi YAML của bạn để JSON và nhập vào dịch vụ đó và bạn nhận được một struct autogenerated.

Và cuối cùng unmarshal như một poster trước đó đã viết:

var service Service 

err = yaml.Unmarshal(yourFile, &service) 
if err != nil { 
    panic(err) 
} 

fmt.Print(service.Metadata.Name) 
Các vấn đề liên quan