在jsonSchema中,您可以使用"必需";属性:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"header": {
"type": "object",
"properties": {
"messageName": {
"type": "string"
},
"messageVersion": {
"type": "string"
}
},
"required": [
"messageName",
"messageVersion"
]
}
},
"required": [
"header"
]
}
在某些情况下,我希望messageVersion字段不是强制性的。有什么方法可以使这个字段的强制性成为有条件的吗?
根据您的情况,有几种不同的方法。我可以想出四种不同的方法来有条件地要求一个字段。
依赖项
dependentSchemas
关键字是应用模式的一种有条件的方式。对于dependentSchemas
中的每个属性,如果该属性存在于正在验证的JSON中,则与该键关联的架构也必须有效如果";foo";属性存在时;条";属性是必需的
{
"type": "object",
"properties": {
"foo": { "type": "string" },
"bar": { "type": "string" }
},
"dependentSchemas": {
"foo": { "required": ["bar"] }
}
}
如果所有依赖模式都需要required
关键字,那么可以使用dependentRequired
关键字作为简写。下面的示例与前面的示例具有相同的效果。
{
"type": "object",
"properties": {
"foo": { "type": "string" },
"bar": { "type": "string" }
},
"dependentRequired": {
"foo": ["bar"]
}
}
注:在草案-07及以下,有一个关键字叫做dependencies
。如果该值是一个模式,则其行为类似于dependentSchemas
。如果该值是一个数组,则其行为类似于dependentRequired
。
含义
如果您的条件取决于字段的值,则可以使用一个称为蕴涵的布尔逻辑概念"A表示B";有效的意思是,如果A为真,那么B也必须为真。蕴涵也可以表示为";!A或B"或者";foo";属性不等于";条";,或";条";属性是必需的。或者,换句话说:如果;foo";属性等于";条";,然后;条";属性是必需的
{
"type": "object",
"properties": {
"foo": { "type": "string" },
"bar": { "type": "string" }
},
"anyOf": [
{
"not": {
"properties": {
"foo": { "const": "bar" }
},
"required": ["foo"]
}
},
{ "required": ["bar"] }
]
}
如果";foo";不等于";条";,#/anyOf/0
匹配,验证成功。如果";foo";等于";条";,#/anyOf/0
失败并且#/anyOf/1
必须有效才能使anyOf
验证成功。
注意:if
/then
关键字具有相同的行为,但更易于阅读和维护。建议仅在使用不支持if
/then
的较旧版本的JSON Schema时使用此方法。
枚举
如果你的条件是基于枚举的,那么它会更直接一些";foo";可以是";条";或";baz";。如果";foo";等于";条";,那么";条";是必需的。如果";foo";等于";baz";,那么";baz";是必需的
{
"type": "object",
"properties": {
"foo": { "enum": ["bar", "baz"] },
"bar": { "type": "string" },
"baz": { "type": "string" }
},
"anyOf": [
{
"properties": {
"foo": { "const": "bar" }
},
"required": ["bar"]
},
{
"properties": {
"foo": { "const": "baz" }
},
"required": ["baz"]
}
]
}
注意:不建议使用此方法,因为它可能会产生令人困惑的错误消息。if
/then
关键字通常是更好的方法。
If Then Else
if
、then
和else
关键字是上述含义模式的简写。这些关键词是在草案-07中添加的如果";foo";属性等于";条";,然后;条";属性是必需的
{
"type": "object",
"properties": {
"foo": { "type": "string" },
"bar": { "type": "string" }
},
"if": {
"properties": {
"foo": { "const": "bar" }
},
"required": ["foo"]
},
"then": { "required": ["bar"] }
}
2017年12月23日编辑:更新了含义部分,并添加了If Then Else部分。
编辑于2018年4月6日:修复If Then Else的错误,并更新单例enum
以使用const
。
编辑07/06/2022:更新依赖项部分使用新的dependentSchemas
/dependentRequired
关键字,而不是dependencies
。
截至2022年,dependencies
已被弃用,并分为dependentRequired
(例如,参见本例)和dependentSchemas
(例如,见本例)。只需使用dependentRequired
即可解决问题:
{
"type": "object",
"properties": {
"foo": { "type": "string" },
"bar": { "type": "string" }
},
"dependentRequired": {
"foo": ["bar"]
}
}
找到了解决方案。使用allOf对我有用。只是完全使用了diff依赖项。
用于draft07模式的正确方法是:
<dependency>
<groupId>com.github.erosb</groupId>
<artifactId>everit-json-schema-jdk6</artifactId>
<version>1.9.2</version>
</dependency>