【问题标题】:Read config in a custom format from yaml file从 yaml 文件中以自定义格式读取配置
【发布时间】:2018-09-30 20:51:51
【问题描述】:

我有一个 YAML 格式的配置文件。我正在尝试以某种自定义格式读取配置。我猜不出我可以选择的任何模式,比如树、json 等。 例如。应用程序.yaml

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

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

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

{"organization/products/product1/manager":"Rob","organization/products/product2/lead":"patrick"}

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

【问题讨论】:

    标签: go yaml


    【解决方案1】:

    这本质上是一个打印树的练习。确切的实现将取决于您选择的特定 YAML 解析器,但几乎所有这些解析器都将具有某种“任何事物的映射”类型。在非常流行的 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
    }
    

    【讨论】:

      猜你喜欢
      • 2016-03-27
      • 1970-01-01
      • 1970-01-01
      • 2012-06-18
      • 1970-01-01
      • 2022-01-14
      • 2018-03-05
      • 2017-01-27
      相关资源
      最近更新 更多