简体   繁体   中英

json schema validation does not work for dependencies?

As far as I understand, using:

    dependencies:
      cake:
        - eggs
        - flour

in a JSON schema validation (I actually parse the schema in YAML, but it should not really matter) should forbid the presence of a cake without an entry for eggs and flour. So this should be rejected:

receip:
  cake: crepes

while this should be accepted:

receip:
  eggs: 3 eggs, given by farmer
  flour: 500g
  cake: crepes

Unfortunately, both cases are accepted in my case. Any idea what I made wrong? I also tried to add another level required as proposed by jsonSchema attribute conditionally required but the problem is the same.

MWE In case it helps, here are all the files that I'm using.

debug_schema.yml :

$schema: https://json-schema.org/draft/2020-12/schema
type: object
properties:
  receip:
    type: object
    properties:
      eggs:
        type: string
      flour:
        type: string
      cake:
        type: string
    dependencies:
      cake:
        - eggs
        - flour

b.yml:

receip:
  ## I'd like to forbid a cake without eggs and flour
  ## Should not validate until I uncomment:
  # eggs: 3 eggs, given by farmer
  # flour: 500g
  cake: crepes

validate_yaml.py

#!/usr/bin/env python3
import yaml
from jsonschema import validate, ValidationError
import argparse

# Instantiate the parser
parser = argparse.ArgumentParser(description='This tool not only checks if the YAML file is correct in term'
                                 + ' of syntex, but it also checks if the structure of the YAML file follows'
                                 + ' the expectations of this project (e.g. that it contains a list of articles,'
                                 + ' with each articles having a title etc…).')
# Optional argument
parser.add_argument('--schema', type=str, default="schema.yml",
                    help='Path to the schema')

parser.add_argument('--yaml', type=str, default="science_zoo.yml",
                    help='Path to the YAML file to verify')

args = parser.parse_args()

class YAMLNotUniqueKey(Exception):
    pass


# By default, PyYAML does not raise an error when two keys are identical, which is an issue here
# see https://github.com/yaml/pyyaml/issues/165#issuecomment-430074049
class UniqueKeyLoader(yaml.SafeLoader):
    def construct_mapping(self, node, deep=False):
        mapping = set()
        for key_node, value_node in node.value:
            key = self.construct_object(key_node, deep=deep)
            if key in mapping:
                raise YAMLNotUniqueKey(f"Duplicate key {key!r} found.")
            mapping.add(key)
        return super().construct_mapping(node, deep)
    
with open(args.schema, "r") as schema_stream:
    try:
        schema = yaml.load(schema_stream, UniqueKeyLoader)
        with open(args.yaml, "r") as yaml_stream:
            try: 
                validate(yaml.load(yaml_stream, UniqueKeyLoader), schema)
                print("The YAML file is correct and follows the schema, congrats! :D")
            except ValidationError as exc:
                print(exc.message)
                print("The problem is located in the JSON at the path {}.".format(exc.json_path))
            except YAMLNotUniqueKey as exc:
                print("ERROR: {}".format(exc))
                print("Rename in the YAML one the two instances of this key to ensure all keys are unique.")
            except yaml.YAMLError as exc:
                print("Errors when trying to load the YAML file:")
                print(exc)

    except YAMLNotUniqueKey as exc:
        print("ERROR: {}".format(exc))
        print("Rename in the schema one the two instances of this key to ensure all keys are unique.")
    except yaml.YAMLError as exc:
        print("Errors when trying to load the schema file:")
        print(exc)

Command:

./validate_yaml.py --yaml b.yml --schema debug_schema.yml 

Oh, so it seems that this keyword has been deprecated , and split into dependentRequired (see eg this example ) and dependentSchemas (see eg this example ). Just using dependentRequired solves the issue:

$schema: https://json-schema.org/draft/2020-12/schema
type: object
properties:
  receip:
    type: object
    properties:
      eggs:
        type: string
      flour:
        type: string
      cake:
        type: string
    dependentRequired:
      cake:
        - eggs
        - flour

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM