使用Python和ObjA
我正在尝试验证ObjB
或beta
等的分配到test.json
({
"alpha": {
"beta": "ObjA"
}
}
)
testschema.json
在我的架构中(beta
)oneOf
a
有多个项目,每个项目定义如下(b
,{{1}的值不同}和c
)
"ObjA": {
"type": "object",
"properties": {
"items": {
"a": [90, 95],
"b": [4, 8],
"c": [0.2, 0.6]
}
},
"additionalProperties": false
}
也就是说,beta
可以采用oneOf
,ObjA
,ObjB
和ObjC
的{{1}}值。我只是想在ObjD
test.json
但是,尝试使用"alpha": {
"type": "object",
"properties": {
"beta": {
"oneOf": [
{
"type": "object",
"properties": {
"ObjA": {
"type": "object",
"properties": {
"items": {
"a": [90, 95],
"b": [4, 8],
"c": [0.2, 0.6]
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
{
"type": "object",
"properties": {
"ObjB": {
"type": "object",
"properties": {
"items": {
"a": [100],
"b": [0],
"c": [0]
}
},
"additionalProperties": false
}
}
},
...
ObjC and ObjD defined
...
}
}
}
},
jsonschema.validate()
我收到以下错误
### Test the whole JSON is valid against the Schema
def test_valid__JSON_against_schema(self):
with open(schema_filename) as schema_file:
test_schema = json.load('testschema.json')
schema_file.close()
with open(json_filename) as json_file:
test_json = json.load('test.json')
json_file.close()
validate(test_json, test_schema)
这是整个消息
Failed validating 'oneOf' in schema['properties']['alpha']['properties']['beta']:
使用在线E
======================================================================
ERROR: test_valid__JSON_against_schema (__main__.SchemaTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_test-variables.py", line 35, in test_valid__JSON_against_schema
validate(test_json, test_schema)
File "/local/tools/PACKAGES/python3/lib/python3.6/site-packages/jsonschema/validators.py", line 541, in validate
cls(schema, *args, **kwargs).validate(instance)
File "/local/tools/PACKAGES/python3/lib/python3.6/site-packages/jsonschema/validators.py", line 130, in validate
raise error
jsonschema.exceptions.ValidationError: 'ObJA' is not valid under any of the given schemas
Failed validating 'oneOf' in schema['properties']['alpha']['properties']['beta']:
{'oneOf': [{'additionalProperties': False,
'properties': {'ObjA': {'additionalProperties': False,
'properties': {'items': {'a': [0.2, 0.6],
'b': [90, 95],
'c': [4, 8]}},
'type': 'object'}},
'type': 'object'},
{'additionalProperties': False,
'properties': {'ObjB': {'additionalProperties': False,
'properties': {'items': {'a': [0],
'b': [100],
'c': [0]}},
'type': 'object'}},
'type': 'object'},
{'additionalProperties': False,
'properties': {'ObjC': {'additionalProperties': False,
'properties': {'items': {'a': [0],
'b': [50],
'c': [50]}},
'type': 'object'}},
'type': 'object'},
{'additionalProperties': False,
'properties': {'ObjD': {'additionalProperties': False,
'properties': {'items': {'a': [100],
'b': [0],
'c': [0]}},
'type': 'object'}},
'type': 'object'}]}
On instance['alpha']['beta']:
'ObjA'
----------------------------------------------------------------------
Ran 1 test in 0.007s
FAILED (errors=1)
验证器(http://json-schema-validator.herokuapp.com/)jsonschema
无法验证,因此我从文件中删除了对test.json
的任何提及(即alpha
})并且验证器报告了以下内容
{ }
恢复[ {
"level" : "warning",
"schema" : {
"loadingURI" : "#",
"pointer" : "/properties/alpha/properties/beta/oneOf/0/properties/ObjA/properties/items"
},
"domain" : "syntax",
"message" : "the following keywords are unknown and will be ignored: [a, b, c]",
"ignored" : [ "a", "b", "c" ]
} ]
,验证提供
test.json
有谁知道这样做的正确方法?
感谢。
答案 0 :(得分:3)
让我们找出失败的架构部分。
{
"type": "object",
"properties": {
"ObjA": {
"type": "object",
"properties": {
"items": {
"a": [90, 95],
"b": [4, 8],
"c": [0.2, 0.6]
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
这是对这部分测试数据进行评估
"ObjA"
您看到的错误告诉您测试数据是一个字符串,但架构要求它是一个对象。
与您的架构匹配的测试数据看起来像这样
{
"ObjA": {
"items": ???
}
}
我在这里使用???
,因为此处的值可以是任何有效JSON的值。原因是因为此架构不包含任何JSON Schema关键字。
{
"a": [90, 95],
"b": [4, 8],
"c": [0.2, 0.6]
}
因此,对它的价值没有限制。您看到的警告消息告诉您a
,b
和c
不是关键字。
我不知道你想用这个模式表达什么,但它与测试数据中的简单字符串相差甚远。
编辑以回应评论
听起来你正试图将JSON Schema用于不适合的东西。模式应该仅描述用户需要关注的内容。您必须在另一个步骤中将用户值映射到硬编码结构。无论如何,听起来你需要enum
而不是oneOf
。
{
"enum": ["ObjA", "ObjB", "ObjC", "ObjD"]
}
或
{
"enum": [
{
"a": [90, 95],
"b": [4, 8],
"c": [0.2, 0.6]
},
{
"a": [100],
"b": [0],
"c": [0]
},
...
]
}
没有办法同时拥有两者。如果您确实需要在架构中表达,我会添加一个显示映射的自定义关键字。验证器将忽略它(并且您可能会收到警告),但这种关系将表达给人类读者和自定义工具。它可能看起来像这样
{
"enum": ["ObjA", "ObjB", "ObjC", "ObjD"]
"enumValues": {
"ObjA": {
"a": [90, 95],
"b": [4, 8],
"c": [0.2, 0.6]
},
"ObjB": {
"a": [100],
"b": [0],
"c": [0]
},
...
]
}
enum
告诉用户允许的值是什么,验证器可以检查这个值。然后enumValues
关键字是我们用来表达枚举值与其实际值之间关系的结果。