我们有需要阅读具有特定结构的YAML文件的工具。当我们得到YAML文件时,我们需要知道是否
- 根据某些指南 - 语义检查
检查YAML文件是否有效- 语法错误(如果有)
醇>
例如,这是我们需要解决的验证示例
_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} }
映射是一个关键的值对象
seq可以有多个构建
输入任何是和键值
我们使用此开源来解析yaml https://github.com/go-yaml/yaml
一个想法(这是好的)是转换为json,如下所示,通过将文件转换为json并验证它有哪些库来支持它,我的上下文中的任何示例都将非常有用https://github.com/xeipuuv/gojsonschema
但不确定我是如何处理的
Type map
Type seq
答案 0 :(得分:3)
这是你可以尝试的。
在预期的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{})
,或者如果您想要强制执行"底层表单是一个键值对象,您可以将其声明为map[string]interface{}
或另一个结构。
然后我们将yaml数据解组到struct:
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
}
在编组/解编中,地图和结构是可以互换的。结构的好处是你可以提前预定义字段的名称,同时解组到地图,它不会让你清楚键是什么。
答案 1 :(得分:0)
您可以使go-yaml
与jsonschema
一起使用。看到此问题:https://github.com/santhosh-tekuri/jsonschema/issues/5
简而言之:
interface{}
jsonschema.ValidateInterface
进行验证。(一旦yaml.v3已发布,则可以使用配置选项替换自定义解组器)
我最初是使用公认的答案的方法来解析为一个结构,然后编写代码以手动验证该结构是否符合我的规范。这很快就变得很丑陋-上述方法允许使用清晰的单独规范并对其进行可靠的验证。