代码之家  ›  专栏  ›  技术社区  ›  Jon

在python中验证yaml文档

  •  43
  • Jon  · 技术社区  · 15 年前

    XML的好处之一是能够根据XSD验证文档。YAML没有这个特性,所以如何验证我打开的YAML文档是否符合我的应用程序所期望的格式?

    10 回复  |  直到 15 年前
        1
  •  17
  •   nealmcb    13 年前

    尝试 Rx ,它有一个Python实现。它适用于JSON和YAML。

    从Rx站点:

    不幸的是,虽然这些格式使得传递复杂的数据结构变得很容易,但是它们缺少一个验证系统。XML有XML模式和RELAXNG,但这些标准很复杂,有时也很混乱。对于JSON提供的那种数据结构,它们的可移植性不强,如果您想避免将XML作为数据编码,那么编写更多的XML来验证第一个XML可能就更没有吸引力了。

        2
  •  41
  •   Jack Kelly    11 年前

    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'
    

    这样做的一个问题是,如果您的模式跨越多个文件,并且您使用 "$ref" 我认为,要引用其他文件,那么这些其他文件需要是JSON。但可能有办法解决这个问题。在我自己的项目中,我正在使用JSON文件指定模式,而实例是YAML。

        3
  •  15
  •   Stabledog Tom Ekberg    4 年前

    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等等。

        5
  •  5
  •   Gringo Suave    12 年前

        6
  •  4
  •   Hari Priya Thangavel    9 年前

    我也有同样的情况。我需要验证YAML的元素。

    首先我认为“PyYAML标签”是最好的简单方法。但后来决定使用“PyKwalify”,它实际上定义了YAML的模式。

    PyYAML标签:

    YAML文件有一个标记支持,我们可以通过给数据类型加前缀来强制执行这个基本检查(e、 g)对于整数-!!内景“123”

    http://pyyaml.org/wiki/PyYAMLDocumentation#Tags 这是好的,但是如果您要向最终用户公开它,那么它可能会引起混淆。 我做了一些研究来定义YAML的模式。这个想法就像我们可以用YAML对应的模式验证基本数据类型检查。此外,甚至我们的自定义验证,如IP地址,随机字符串可以添加在这个。所以我们可以单独使用模式,让YAML简单易读。

    PyKwalify公司:

    有一个名为PyKwalify的软件包用于此目的: https://pypi.python.org/pypi/pykwalify

    这个包裹最符合我的要求。 我尝试了一个小例子,在我的本地设置,这是工作。下面是示例模式文件。

    #sample schema
    
    type: map
    mapping:
        Emp:
            type:    map
            mapping:
                name:
                    type:      str
                    required:  yes
                email:
                    type:      str
                age:
                    type:      int
                birth:
                    type:     str
    

    此架构的有效YAML文件

    ---
    Emp:
        name:   "abc"
        email:  "xyz@gmail.com"
        age:    yy
        birth:  "xx/xx/xxxx"
    

    谢谢

        7
  •  4
  •   flipback    6 年前

    您可以将YAML文档作为 口述 使用图书馆 架构 要检查它:

    from schema import Schema, And, Use, Optional, SchemaError
    import yaml
    
    schema = Schema(
            {
                'created': And(datetime.datetime),
                'author': And(str),
                'email': And(str),
                'description': And(str),
                Optional('tags'): And(str, lambda s: len(s) >= 0),
                'setup': And(list),
                'steps': And(list, lambda steps: all('=>' in s for s in steps), error='Steps should be array of string '
                                                                                      'and contain "=>" to separate'
                                                                                      'actions and expectations'),
                'teardown': And(list)
            }
        )
    
    with open(filepath) as f:
       data = yaml.load(f)
       try:
           schema.validate(data)
       except SchemaError as e:
           print(e)
    
        8
  •  1
  •   yaccob    7 年前

    我包装了一些现有的与json相关的python库 yaml .

    • jsonschema json 文件 json-schema 文件,正在包装以支持验证 亚马尔 文件 json模式 中的文件 亚马尔 -格式也一样。

    • jsonpath-ng -实现 JSONPath 对于python,被包装以支持 选择直接打开 亚马尔

    ... 在github上提供:

    https://github.com/yaccob/ytools

    可以使用 pip :

    pip install ytools

    验证示例(来自 https://github.com/yaccob/ytools#validation

    import ytools
    ytools.validate("test/sampleschema.yaml", ["test/sampledata.yaml"])
    

    亚马尔 格式也一样。

    ytools 它没有提供任何以前不存在的东西—它只是使一些现有解决方案的应用更加灵活和方便。

        9
  •  0
  •   jaiks    8 年前

    #!/usr/bin/env python
    
    import yaml
    
    with open("example.yaml", 'r') as stream:
        try:
            print(yaml.load(stream))
        except yaml.YAMLError as exc:
            print(exc)
    

    可以通过exc.problem访问错误消息

    访问 exc.problem_mark <yaml.error.Mark> 对象。

    此对象允许您访问属性

    • 线

    因此,您可以创建自己的问题指针:

    pm = exc.problem_mark
    print("Your file {} has an issue on line {} at position {}".format(pm.name, pm.line, pm.column))
    
        10
  •  -1
  •   ars    15 年前

    我不知道python解决方案。但是有一个用于YAML的ruby模式验证器叫做 kwalify