我们有工具需要读取具有特定结构的 YAML 文件。当我们得到 YAML 文件时,我们需要知道是否
- Check if the YAML file is valid according to some guideline - semantic check
- 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/