使用golang验证yaml模式(语义检查)

5 validation schema yaml go dockerfile

我们有工具需要读取具有特定结构的YAML文件。当我们获得YAML文件时,我们需要知道

  1. 根据一些准则检查YAML文件是否有效-语义检查
  2. 语法错误在哪里(如果有)

例如,这是我们需要解决的验证示例

 _version:  {required: true}
   id: {required: true, pattern: '/^[A-Za_\-\.]+$/'}   
   release-version: {required: true}
   type:   

   builds:
     type:seq
     sequence:
       -type:map
     mapping:
        name:{required: true, unique: true, pattern: '/^[A-Za-z0-3_\-\.]+$/'}
        params: 
          type: map
          mapping: { =: {type: any} } 
Run Code Online (Sandbox Code Playgroud)

映射是键值对象
seq可以具有多个构建
类型,包括is和键值

我们使用此开放源代码解析yaml https://github.com/go-yaml/yaml

一个想法(很好)是像下面这样转换为json:将文件转换为json并验证它具有支持它的库,在我的上下文中的任何示例都将非常有用https://github.com/ xeipuuv / gojsonschema

但不确定我该如何处理

Type map
Type seq
Run Code Online (Sandbox Code Playgroud)

Pie*_*Pah 5

这是你可以尝试的。

根据预期 yaml 数据的形状对结构进行建模:

type Config struct {
        Version struct {
                Required bool
        }
        ID struct {
                Required bool
                Pattern string
        }
        ReleaseVersion struct {
                Required bool
        }
        Type interface{}
        Builds struct {
                Type []interface{} `yaml:"type"`
                Sequence struct {
                        Type string
                }
                Mapping struct {
                        Name map[string]interface{}
                        Params struct {
                                Type string `yaml:"type"`
                                Mapping struct {
                                        To map[string]string `yaml:"="`
                                }
                        }
                } `yaml:"mapping"`              
        }
}
Run Code Online (Sandbox Code Playgroud)

添加yaml 标志yaml:"somefield"来标记我们感兴趣的数据的 yaml 的字段名称。

此外,许多具有未知/未确定类型的字段可以声明为空接口(interface{}),或者如果您想“强制”底层形式是键值对象,您可以将其声明为一个map[string]interface{}或另一个结构。

然后我们将 yaml 数据解组到结构中:

cfg := Config{}
err := yaml.Unmarshal([]byte(data), &cfg)
if err != nil {
        log.Fatalf("error: %v", err)
}
Run Code Online (Sandbox Code Playgroud)

由于我们将字段建模为匿名结构或映射,因此我们可以通过检查特定字段与 的相等性来测试它是否具有“键值”值nil

// Mapping is a key value object
if (Mapping != nil) {
        // Mapping is a key-value object, since it's not nil.
}


// type any is and key value
// Mapping.To is declared with map[string]string type
// so if it's not nil we can say there's a map there.
if (Mapping.To != nil) {
        // Mapping.To is a map
}
Run Code Online (Sandbox Code Playgroud)

在编组/解组中,映射和结构可以很好地互换。结构的好处是您可以提前预定义字段的名称,同时解组到映射,您将不清楚键是什么。

  • 非常感谢1+!我找到了这个 https://github.com/docker/libcompose/blob/master/config/schema.go 和这个 https://github.com/docker/compose/blob/master/compose/config/config_schema_v2。 0.json ,如果您需要以您选择的方式进行操作,为了简单起见并且不陷入死胡同,您认为如何? (2认同)