从yaml文件中以自定义格式读取配置

时间:2018-04-20 07:40:42

标签: go yaml

我有一个YAML格式的配置文件。我试图以一些自定义格式读取配置。我想不出任何我可以去的模式,如树,json等。 例如。 application.yaml

function getDescriptions(){

    var cities = {
    'Cannes': '', 'London': '', 'Amsterdam': '', 'Berlin': ''} 
    for (var city in cities) {
       $.ajax({
          url: 'http://api.openweathermap.org/data/2.5/forecast/daily?q=' + city + "&units=metric" + "&cnt=8" + "&APPID=***",
          type: "GET",
          dataType: "jsonp",
          success: function(data){         
              cities[city] = data.weather[0].description;            

          }                       
      });  
      document.write(city+ "- " + cities[city])
    }
}

配置文件可能包含大量信息,并且可能因文件而异。我想用以下格式构建数据,

organization:
  products:
    product1:
      manager: "Rob"
      engineer: "John"
    product2:
      manager: "Henry"
      lead: "patrick"

OR

organization/products/product1/manager  =  Rob
organization/products/product1/engineer = John
organization/products/product2/lead     = patrick

知道如何实现这种模式吗?

1 个答案:

答案 0 :(得分:0)

这实际上是印刷树木的练习。确切的实现将取决于您选择的特定YAML解析器,但几乎所有这些都将具有某种"任何地图#34;类型。在非常流行的gopkg.in/yaml.v2中,这种类型被命名为MapSlice(不要让这个名称混淆你;它泄漏了它的实现,它必须处理灵活的密钥类型)。

将它扔到您最喜欢的树遍历算法上以渲染文本文件。这是一个只使用字符串键和一些标量叶节点的简单示例:

package main

import (
    "bytes"
    "fmt"
    "io"
    "log"
    "path/filepath"
)

func main() {
    var tree yaml.MapSlice
    if err := yaml.Unmarshal(input, &tree); err != nil {
        log.Fatal(err)
    }

    var buf bytes.Buffer
    if err := render(&buf, tree, ""); err != nil {
        log.Fatal(err)
    }
}

func render(w io.Writer, tree yaml.MapSlice, prefix string) error {
    for _, branch := range tree {
        key, ok := branch.Key.(string)
        if !ok {
            return fmt.Errorf("unsupported key type: %T", branch.Key)
        }

        prefix := filepath.Join(prefix, key)

        switch x := branch.Value.(type) {
        default:
            return fmt.Errorf("unsupported value type: %T", branch.Value)

        case yaml.MapSlice:
            // recurse
            if err := render(w, x, prefix); err != nil {
                return err
            }
            continue

        // scalar values
        case string:
        case int:
        case float64:
        // ...
        }

        // print scalar
        if _, err := fmt.Fprintf(w, "%s = %v\n", prefix, branch.Value); err != nil {
            return err
        }
    }

    return nil
}