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

标签 validation go schema yaml dockerfile

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

  1. Check if the YAML file is valid according to some guideline - semantic check
  2. Where is the syntax error if any

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

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

Mapping is a key value object
seq can have multiple builds
type any is and key value

我们使用这个开源来解析yaml https://github.com/go-yaml/yaml

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

但不确定我是如何处理的

Type map
Type seq

最佳答案

这是您可以尝试的方法。

按照预期的 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"`              
        }
}

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

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

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

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

由于我们将字段建模为匿名结构或映射,因此我们可以通过检查其是否等于 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
}

在编码(marshal)处理/解封处理中,映射和结构是可以互换的。结构的好处是您可以在解码到映射时提前预定义字段的名称,因为您不清楚键是什么。

关于validation - 使用 golang 验证 yaml 模式(语义检查),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49442799/

相关文章:

javascript - 如何验证 HTML 表单中至少 3 个单词?

user-interface - 如何在 QML 中创建一个没有标题栏但带有关闭/最小化/最大化按钮的窗口?

mysql - 创建投票应用程序。需要有关计票数据库结构的建议

java - 尝试将架构应用于 JSON 数据时,SPARK 数据帧返回 null

database - 推荐的全局化引用资料

Angular 形式验证 : compare two fields in different form groups

ruby-on-rails - 确保模型属性始终小写和剥离的最佳方法?

c# - 如何在运行时使用错误提供程序以及关联任何控件以进行验证

string - Golang 中的 string 和 .String() 问题

google-app-engine - 正确使用 map[string]interface{}?