在Python中验证YAML文档
XML的一个好处是可以通过XSD来验证文档的正确性。可是,YAML没有这个功能。那么,我该怎么确认我打开的YAML文档是我的应用程序所期望的格式呢?
11 个回答
29
我觉得Cerberus非常可靠,文档也很完善,使用起来很简单。
下面是一个基本的实现示例:
my_yaml.yaml
:
name: 'my_name'
date: 2017-10-01
metrics:
percentage:
value: 87
trend: stable
在schema.py
中定义验证规则:
{
'name': {
'required': True,
'type': 'string'
},
'date': {
'required': True,
'type': 'date'
},
'metrics': {
'required': True,
'type': 'dict',
'schema': {
'percentage': {
'required': True,
'type': 'dict',
'schema': {
'value': {
'required': True,
'type': 'number',
'min': 0,
'max': 100
},
'trend': {
'type': 'string',
'nullable': True,
'regex': '^(?i)(down|equal|up)$'
}
}
}
}
}
}
使用PyYaml来加载一个yaml
文档:
import yaml
def load_doc():
with open('./my_yaml.yaml', 'r') as stream:
try:
return yaml.load(stream)
except yaml.YAMLError as exception:
raise exception
## Now, validating the yaml file is straightforward:
from cerberus import Validator
schema = eval(open('./schema.py', 'r').read())
v = Validator(schema)
doc = load_doc()
print(v.validate(doc, schema))
print(v.errors)
请记住,Cerberus是一个通用的数据验证工具,这意味着它不仅支持YAML格式,还可以支持其他格式,比如JSON、XML等等。
63
因为JSON和YAML这两种格式很相似,你可以使用JSON-Schema来验证一部分YAML的内容。下面是一个代码示例(你需要安装PyYAML和jsonschema):
from jsonschema import validate
import yaml
schema = """
type: object
properties:
testing:
type: array
items:
enum:
- this
- is
- a
- test
"""
good_instance = """
testing: ['this', 'is', 'a', 'test']
"""
validate(yaml.load(good_instance), yaml.load(schema)) # passes
# Now let's try a bad instance...
bad_instance = """
testing: ['this', 'is', 'a', 'bad', 'test']
"""
validate(yaml.load(bad_instance), yaml.load(schema))
# Fails with:
# ValidationError: 'bad' is not one of ['this', 'is', 'a', 'test']
#
# Failed validating 'enum' in schema['properties']['testing']['items']:
# {'enum': ['this', 'is', 'a', 'test']}
#
# On instance['testing'][3]:
# 'bad'
不过有一个问题,如果你的模式(schema)跨越多个文件,并且你用"$ref"
来引用其他文件,那么那些其他文件可能需要是JSON格式。我想是这样的。不过可能有其他解决办法。在我自己的项目中,我尝试用JSON文件来定义模式,而实例则使用YAML格式。
14
试试Rx吧,它有Python的实现,支持处理JSON和YAML格式的数据。
在Rx网站上说:
“当你给你的网络服务添加一个API时,你需要选择一种方式来编码你要发送的数据。XML是一个常见的选择,但它很快就会变得复杂和麻烦。很多网络服务的开发者希望避免使用XML,而是选择一些简单的数据格式,这些格式能对应现代编程语言中常见的数据结构。换句话说,就是JSON和YAML。”
不过,虽然这些格式让传递复杂数据结构变得简单,但它们没有验证数据的系统。XML有XML模式和RELAX NG这样的工具,但这些标准复杂且有时让人困惑。它们不太适合JSON这种数据结构,如果你想避免使用XML来编码数据,那么为了验证第一个XML而写更多的XML,可能就更让人头疼了。
Rx的目的是提供一个与JSON风格的数据结构相匹配的数据验证系统,并且使用起来和JSON一样简单。