JSON模式属性具有比预期更广的范围

时间:2017-07-21 14:17:08

标签: python json jsonschema

我在Python3中测试了以下JSON模式(testschema.json)。 我一直收到属性"alpha"的验证错误,我尝试以各种方式宣布该属性无济于事。

{
    "id": "testschema",
    "$schema": "http://json-schema.org/draft-04/schema#",
    "description": "test schema",

    "type": "object",
    "properties": {


        "traffic_parameters": {

            "properties": {

                "test_type": {

                    "type": "string",
                    "enum": ["AA", "BB"]
                },

                "capacity": {

                    "oneOf": [
                        {
                            "properties": {

                                "min_percentage": {

                                    "type": "integer",
                                    "minimum" : 1,
                                    "maximum" : 150,
                                    "additionalProperties": false
                                },

                                "max_percentage": {

                                    "type": "integer",
                                    "minimum" : 1,
                                    "maximum" : 150,
                                    "additionalProperties": false
                                }
                            },

                            "additionalProperties": false
                        },

                        {
                            "properties": {

                                "percentage_range": {

                                    "type": "array",
                                    "minItems": 1,
                                    "maxItems": 10,
                                    "items": {

                                        "type": "integer"
                                    },

                                   "additionalProperties": false
                                }
                            },

                            "additionalProperties": false
                        }                    
                    ]
                }
            },

            "additionalProperties": false
        },


        "alpha": {

            "properties": {

                "beta": {

                    "oneOf": [
                        {
                            "properties": {

                                "AA": {

                                    "a":   [90, 95],
                                    "b":   [4, 8],
                                    "additionalProperties": false
                                }
                            },

                            "additionalProperties": false
                        },

                        {
                            "properties": {

                                "BB": {

                                    "a":   [100],
                                    "b":   [0],
                                    "c": [0],
                                    "additionalProperties": false
                                }
                            },

                            "additionalProperties": false
                        },

                        {
                            "properties": {

                                "CC": {

                                    "a":   [50],
                                    "b":   [50],
                                    "additionalProperties": false
                                }
                            },

                            "additionalProperties": false
                        },

                        {
                            "properties": {

                                "DD": {

                                    "a":   [0],
                                    "b":   [0],
                                    "c": [100],
                                    "additionalProperties": false  
                                }
                            },

                            "additionalProperties": false
                        }
                    ]
                }
            },

            "additionalProperties": false
        }
    },

    "required": ["traffic_parameters", "alpha"]
}

以下是使用此架构的测试JSON(test.json)。

{
    "traffic_parameters": {

        "test_type": "BB",

        "capacity": {

            "percentage_range": [1,2,3,4,5,6]
        }
     },

    "alpha": {

        "beta": "AA"
    }
}

当我使用Python3 jsonschema模块

验证时
with open("testschema.json") as schema_file:
    test_schema = json.load(schema_file)
schema_file.close()

with open("test.json") as json_file:
    test_json = json.load(json_file)
json_file.close()

validate(test_json, test_schema)

我在alpha属性上遇到错误,该属性在结构上类似于traffic_parameters并没有错误。

jsonschema.exceptions.ValidationError: 'AA' is valid under each of {'properties': {'BB': ...

这是输出

E
======================================================================
ERROR: test_valid__JSON_against_schema (__main__.SchemaTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test.py", line 35, in test_valid__JSON_against_schema
    validate(test_json, test_schema)
  File "/local/tools/PACKAGES/pyhton3/lib/python3.6/site-packages/jsonschema/validators.py", line 541, in validate
    cls(schema, *args, **kwargs).validate(instance)
  File "/local/tools/PACKAGES/pyhton3/lib/python3.6/site-packages/jsonschema/validators.py", line 130, in validate
    raise error
jsonschema.exceptions.ValidationError: 'AA' is valid under each of {'properties': {'BB': {'a': [100], 'b': [0], 'c': [0], 'additionalProperties': False}}, 'additionalProperties': False}, {'properties': {'CC': {'a': [50], 'b': [50], 'additionalProperties': False}}, 'additionalProperties': False}, {'properties': {'DD': {'a': [0], 'b': [0], 'c': [100], 'additionalProperties': False}}, 'additionalProperties': False}, {'properties': {'AA': {'a': [90, 95], 'b': [4, 8], 'additionalProperties': False}}, 'additionalProperties': False}

Failed validating 'oneOf' in schema['properties']['alpha']['properties']['beta']:
    {'oneOf': [{'additionalProperties': False,
                'properties': {'AA': {'a': [90, 95],
                                      'additionalProperties': False,
                                      'b': [4, 8]}}},
               {'additionalProperties': False,
                'properties': {'BB': {'a': [100],
                                      'additionalProperties': False,
                                      'b': [0],
                                      'c': [0]}}},
               {'additionalProperties': False,
                'properties': {'CC': {'a': [50],
                                      'additionalProperties': False,
                                      'b': [50]}}},
               {'additionalProperties': False,
                'properties': {'DD': {'a': [0],
                                      'additionalProperties': False,
                                      'b': [0],
                                      'c': [100]}}}]}

On instance['alpha']['beta']:
    'AA'

----------------------------------------------------------------------
Ran 1 test in 0.007s

FAILED (errors=1)

有谁知道这是为什么以及如何解决它?

感谢。

1 个答案:

答案 0 :(得分:3)

我打算将模式缩短到足以重现验证失败:

{
    "id": "testschema",
    "$schema": "http://json-schema.org/draft-04/schema#",
    "description": "test schema",
    "type": "object",
    "properties": {
        "alpha": {
            "properties": {
                "beta": {
                    "oneOf": [
                        {
                            "properties": {
                                "AA": {
                                    "a":   [90, 95],
                                    "b":   [4, 8],
                                    "additionalProperties": false
                                }
                            },
                            "additionalProperties": false
                        },
                        {
                            "properties": {
                                "BB": {
                                    "a":   [100],
                                    "b":   [0],
                                    "c": [0],
                                    "additionalProperties": false
                                }
                            },
                            "additionalProperties": false
                        }
                    ]
                }
            },
            "additionalProperties": false
        }
    },
    "required": [ "alpha" ]
}

该错误表示无法验证oneOf约束,因为"AA"成功验证了oneOf中列出的每个架构,oneOf要求它必须匹配一个只有一个。

为什么"AA"会针对每个架构进行验证?根本原因是模式没有为"type"中列出的每个模式指定oneOf信息。正如here所解释的,如果没有为模式指定"type",那么任何类型的任何有效JSON都可能与该模式匹配。要解决此问题,我们需要添加缺少的"type"约束。

从查看架构和JSON示例,我不确定您想要实现的目标。模式似乎是将"AA""BB"等描述为嵌套对象,但JSON示例似乎表明"beta"只需要映射到像{{1}这样的字符串值}}

如果JSON示例是正确的信息源,您可以使用这样的架构解决问题。

"AA"

OTOH,如果您的目标是将schema = json.loads(''' { "id": "testschema", "$schema": "http://json-schema.org/draft-04/schema#", "description": "test schema", "type": "object", "properties": { "alpha": { "type": "object", "properties": { "beta": { "type": "string", "enum": [ "AA", "BB", "CC", "DD" ] } }, "additionalProperties": false } }, "required": [ "alpha" ] } ''') # valid validate(json.loads(''' { "alpha": { "beta": "AA" } } '''), schema) # valid validate(json.loads(''' { "alpha": { "beta": "BB" } } '''), schema) # invalid validate(json.loads(''' { "alpha": { "beta": "ZZ" } } '''), schema) Traceback (most recent call last): File "<stdin>", line 7, in <module> File "/Library/Python/2.7/site-packages/jsonschema/validators.py", line 541, in validate cls(schema, *args, **kwargs).validate(instance) File "/Library/Python/2.7/site-packages/jsonschema/validators.py", line 130, in validate raise error jsonschema.exceptions.ValidationError: u'ZZ' is not one of [u'AA', u'BB', u'CC', u'DD'] Failed validating u'enum' in schema[u'properties'][u'alpha'][u'properties'][u'beta']: {u'enum': [u'AA', u'BB', u'CC', u'DD'], u'type': u'string'} On instance[u'alpha'][u'beta']: u'ZZ' "AA"等作为子对象,那么您可以通过将架构更改为此类来修复它。

"BB"

无论哪种方式,重要的是确保在必要时指定schema = json.loads(''' { "id": "testschema", "$schema": "http://json-schema.org/draft-04/schema#", "description": "test schema", "type": "object", "properties": { "alpha": { "type": "object", "properties": { "beta": { "oneOf": [ { "type": "object", "properties": { "AA": { "type": "object", "properties": { "a": { "type": "array" } } } }, "additionalProperties": false }, { "type": "object", "properties": { "BB": { "type": "object", "properties": { "b": { "type": "array" } } } }, "additionalProperties": false } ] } }, "additionalProperties": false } }, "required": [ "alpha" ] } ''') # valid validate(json.loads(''' { "alpha": { "beta": { "AA": { "a": [ 1 ] } } } } '''), schema) # valid validate(json.loads(''' { "alpha": { "beta": { "BB": { "b": [ 1 ] } } } } '''), schema) # invalid validate(json.loads(''' { "alpha": { "beta": { "ZZ": { "z": [ 1 ] } } } } '''), schema) Traceback (most recent call last): File "<stdin>", line 11, in <module> File "/Library/Python/2.7/site-packages/jsonschema/validators.py", line 541, in validate cls(schema, *args, **kwargs).validate(instance) File "/Library/Python/2.7/site-packages/jsonschema/validators.py", line 130, in validate raise error jsonschema.exceptions.ValidationError: {u'ZZ': {u'z': [1]}} is not valid under any of the given schemas Failed validating u'oneOf' in schema[u'properties'][u'alpha'][u'properties'][u'beta']: {u'oneOf': [{u'additionalProperties': False, u'properties': {u'AA': {u'properties': {u'a': {u'type': u'array'}}, u'type': u'object'}}, u'type': u'object'}, {u'additionalProperties': False, u'properties': {u'BB': {u'properties': {u'b': {u'type': u'array'}}, u'type': u'object'}}, u'type': u'object'}]} On instance[u'alpha'][u'beta']: {u'ZZ': {u'z': [1]}} # invalid validate(json.loads(''' { "alpha": { "beta": { "AA": { "a": [ 1 ] }, "BB": { "b": [ 1 ] } } } } '''), schema) Traceback (most recent call last): File "<stdin>", line 14, in <module> File "/Library/Python/2.7/site-packages/jsonschema/validators.py", line 541, in validate cls(schema, *args, **kwargs).validate(instance) File "/Library/Python/2.7/site-packages/jsonschema/validators.py", line 130, in validate raise error jsonschema.exceptions.ValidationError: {u'AA': {u'a': [1]}, u'BB': {u'b': [1]}} is not valid under any of the given schemas Failed validating u'oneOf' in schema[u'properties'][u'alpha'][u'properties'][u'beta']: {u'oneOf': [{u'additionalProperties': False, u'properties': {u'AA': {u'properties': {u'a': {u'type': u'array'}}, u'type': u'object'}}, u'type': u'object'}, {u'additionalProperties': False, u'properties': {u'BB': {u'properties': {u'b': {u'type': u'array'}}, u'type': u'object'}}, u'type': u'object'}]} On instance[u'alpha'][u'beta']: {u'AA': {u'a': [1]}, u'BB': {u'b': [1]}} 信息。