我正在使用JSON Schema的Draft-04。是否可以根据子属性的存在来设置依赖关系,和/或依赖于子属性?或者我被迫使用allOf
来管理这些类型的依赖项?
我有以下内容(您可以在https://repl.it/@neverendingqs/JsonSchemaNestedDependencies播放):
'use strict';
const Ajv = require('ajv');
const assert = require('chai').assert;
// Using ajv@5.5.1
const draft4 = require('ajv/lib/refs/json-schema-draft-04.json');
const schema = {
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"foo1": {
"type": [ "object" ],
"properties": {
"bar1": { "type": "string" }
}
},
"foo2": {
"type": [ "object" ],
"properties": {
"bar2": { "type": "string" }
}
}
},
"dependencies": {
"foo1": ["foo2"],
// Is this possible?
"foo1/bar1": ["foo2/bar2"]
}
};
const schemaName = 'my-schema';
const ajv = new Ajv();
ajv.addMetaSchema(draft4);
ajv.addSchema(schema, schemaName);
assert.isTrue(
ajv.validate(schemaName, {
"foo1": { "bar1": "a" },
"foo2": { "bar2": "c" }
}),
ajv.errorsText(ajv.errors, { dataVar: 'event' })
);
assert.isFalse(ajv.validate(schemaName, {
"foo1": { "bar1": "a" }
}));
// Looking to cause this to pass
assert.isFalse(ajv.validate(schemaName, {
"foo1": { "bar1": "a" },
"foo2": {}
}));
我正在寻找Draft-04的答案,但我也对使用后期规范的答案感兴趣。
编辑: Draft-04 是指http://json-schema.org/specification-links.html#draft-4下的规范。具体来说,我使用的是dependencies
,它是在验证规范(https://tools.ietf.org/html/draft-fge-json-schema-validation-00)
答案 0 :(得分:0)
在草案4中实现这一点非常棘手!
您可以在草稿4中使用required
来创建对象中所需的属性...
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"foo1": {
"type": [ "object" ],
"properties": {
"bar1": { "type": "string" }
}
},
"foo2": {
"type": [ "object" ],
"properties": {
"bar2": { "type": "string" }
},
"required": [ "bar2" ]
}
}
}
我无法在repl.it中重新运行此更改,但我使用https://www.jsonschemavalidator.net
针对您要失败的架构进行了检查对于draft-7(在撰写本文时最新),您可以使用if
,then
,else
,这可能更直观,但我认为你' d仍然需要使用required
来实现这一点,因为您希望if
中的子模式通过或失败。 Keywords for Applying Subschemas Conditionally
答案 1 :(得分:0)
如果dependencies
支持JSON指针会很好,但事实并非如此。你必须用暗示来解决这个问题。我已经使用definitions
将其分解,以帮助更清楚地了解正在发生的事情。
首先,我为我们要检查的案例定义模式:/foo1/bar1
存在且/foo2/bar2
存在。根据这两个定义,我使用anyOf
表示/foo1/bar1
不存在,或者/foo2/bar2
是必需的。换句话说,/foo1/bar1
暗示/foo2/bar2
。
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"foo1": {
"type": [ "object" ],
"properties": {
"bar1": { "type": "string" }
}
},
"foo2": {
"type": [ "object" ],
"properties": {
"bar2": { "type": "string" }
}
}
},
"allOf": [{ "$ref": "#/definitions/foo1-bar1-implies-foo2-bar2" }],
"dependencies": {
"foo1": ["foo2"]
},
"definitions": {
"foo1-bar1-implies-foo2-bar2": {
"anyOf": [
{ "not": { "$ref": "#/definitions/foo1-bar1" } },
{ "$ref": "#/definitions/foo2-bar2" }
]
},
"foo1-bar1": {
"properties": {
"foo1": { "required": ["bar1"] }
},
"required": ["foo1"]
},
"foo2-bar2": {
"properties": {
"foo2": { "required": ["bar2"] }
},
"required": ["foo2"]
}
}
}