2015-02-23 57 views
7

我想用Go解析yaml文件。不幸的是我無法弄清楚如何。 YAML的文件,我是這樣的:去解析yaml文件

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

我有這樣的Go代碼,但它不工作:

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) 
} 

當我運行它,我得到一個錯誤。我認爲這是因爲我沒有爲src和dst鍵/值創建結構。僅供參考:當我將其更改爲列表時,它可以正常工作。

所以上面的代碼解析此:

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

回答

5

嗯,我想我已經通過我自己琢磨出來。以下代碼可以正常工作。任何建議/改進?

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

嘗試更地道'FirewallNetworkRules'並添加標籤結構捕捉YAML格式 - 例如''yaml:「firewall_network_rules」'' 請參閱這裏瞭解YAML庫中結構標籤使用情況的文檔:http://godoc.org/gopkg.in/yaml.v2#Marshal – elithrar 2015-02-23 23:51:42

+0

感謝您的建議,它確實澄清我的代碼。 – 2015-02-24 08:01:10

3

如果你不關心規則名稱,爲什麼不組織你的yaml文件?

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

因此,代碼會是這樣的,它是乾淨的,可擴展的:

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

如果你使用谷歌雲或kubernetes更具體的工作,要分析這樣的service.yaml :

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 

提供一個真實世界的例子,以便您瞭解如何編寫嵌套。

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"` 
} 

有稱爲便捷的服務JSON-到去https://mholt.github.io/json-to-go/它轉換JSON走結構,只是轉換你的YAML以JSON和輸入到該服務,你會得到一個自動生成的結構。

而在去年的解組作爲以前的海報中寫道:

var service Service 

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

fmt.Print(service.Metadata.Name)