Json 架构:仅当特定 属性 存在于深层嵌套对象中时才需要 属性
Json Schema: Require a property only when a specific property is present in a deep nested object
我需要构建一个 json 架构(草稿 4),它需要一个 属性 基于另一个嵌套对象中 属性 的存在。我已经搜索并尝试了很多东西(anyOf,oneOf,not,dependencies)但没有运气。
也许这在 json 架构中是不可能的?
这是我的简化架构:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"required": ["dog"],
"properties": {
"dog": {
"type": "object",
"required": ["bananas"],
"properties": {
"bananas": { "$ref": "bananas.json" },
"thing": {
"type": "object",
"properties": {
"total": { "type": "string" }
}
}
}
}
}
}
这是bananas.json
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"required": ["banana"],
"definitions": {
"non-empty-string": {
"type": "string",
"minLength": 1
}
},
"properties": {
"banana": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["unit"],
"properties": {
"unit": { "type": "string" },
"thing": {
"type": "object",
"anyOf": [
{ "required": [ "tax_transfers" ] },
{ "required": [ "tax_retentions" ] }
],
"properties": {
"tax_transfers": {
"type": "object",
"required": ["tax_transfer"],
"properties": {
"tax_transfer": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"properties": {
"rate": { "type": "string" }
}
}
}
}
},
"tax_retentions": {
"type": "object",
"required": ["tax_retention"],
"properties": {
"tax_retention": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"properties": {
"rate": { "type": "string" }
}
}
}
}
}
}
}
}
}
}
}
}
我需要当数组中的一个或多个对象具有 'thing' 属性(在 bananas -> banana -> thing)。
然后 属性 'thing' at (dog -> thing) 应该是必需的。
任何帮助将不胜感激。
你需要两件事来表达你的约束。第一个是 "contains",另一个是 "implication"。我在 definitions
部分组织了每一个。
包含
items
关键字允许我们要求数组中的所有项都对模式有效。如果数组中的所有项目都对架构无效,那么我们知道至少有一项是有效的。
{
"not": {
"items": { "not": { ... schema ... } }
}
}
如果您能够升级到 JSON Schema draft-06,则添加了 contains
关键字以简化此过程。
{
"contains": { ... schema ... }
}
蕴涵
蕴涵允许你做一些类似条件的事情。如果条件为真或约束为真(或两者都为真),则条件模式暗示约束模式。这实际上等同于说,如果条件为真,则约束条件也必须为真。
{
"anyOf": [
{ "not": { ... condition schema ... } },
{ ... constraint schema ... }
]
}
JSON Schema draft-07 添加了 if
-then
-else
关键字,试图更好地解决这种情况。我个人不喜欢这样做的方式,所以我会坚持这种事情的暗示模式,但这里是为了以防你想尝试它。
{
"if": { ... schema ... },
"then": { ... schema ... },
"else": { ... schema ... }
}
一起
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"required": ["dog"],
"properties": {
"dog": {
"type": "object",
"required": ["bananas"],
"properties": {
"bananas": { "$ref": "bananas.json" },
"thing": { "type": "object" }
}
}
},
"allOf": [
{ "$ref": "#/definitions/banana-things-implies-dog-things" }
],
"definitions": {
"banana-has-things": {
"properties": {
"dog": {
"properties": {
"bananas": {
"properties": {
"banana": {
"not": {
"items": { "not": { "required": ["things"] } }
}
}
}
}
}
}
}
},
"banana-things-implies-dog-things": {
"anyOf": [
{ "not": { "$ref": "#/definitions/banana-has-things" }},
{
"properties": {
"dog": { "required": ["things"] }
}
}
]
}
}
}
我需要构建一个 json 架构(草稿 4),它需要一个 属性 基于另一个嵌套对象中 属性 的存在。我已经搜索并尝试了很多东西(anyOf,oneOf,not,dependencies)但没有运气。
也许这在 json 架构中是不可能的?
这是我的简化架构:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"required": ["dog"],
"properties": {
"dog": {
"type": "object",
"required": ["bananas"],
"properties": {
"bananas": { "$ref": "bananas.json" },
"thing": {
"type": "object",
"properties": {
"total": { "type": "string" }
}
}
}
}
}
}
这是bananas.json
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"required": ["banana"],
"definitions": {
"non-empty-string": {
"type": "string",
"minLength": 1
}
},
"properties": {
"banana": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["unit"],
"properties": {
"unit": { "type": "string" },
"thing": {
"type": "object",
"anyOf": [
{ "required": [ "tax_transfers" ] },
{ "required": [ "tax_retentions" ] }
],
"properties": {
"tax_transfers": {
"type": "object",
"required": ["tax_transfer"],
"properties": {
"tax_transfer": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"properties": {
"rate": { "type": "string" }
}
}
}
}
},
"tax_retentions": {
"type": "object",
"required": ["tax_retention"],
"properties": {
"tax_retention": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"properties": {
"rate": { "type": "string" }
}
}
}
}
}
}
}
}
}
}
}
}
我需要当数组中的一个或多个对象具有 'thing' 属性(在 bananas -> banana -> thing)。 然后 属性 'thing' at (dog -> thing) 应该是必需的。
任何帮助将不胜感激。
你需要两件事来表达你的约束。第一个是 "contains",另一个是 "implication"。我在 definitions
部分组织了每一个。
包含
items
关键字允许我们要求数组中的所有项都对模式有效。如果数组中的所有项目都对架构无效,那么我们知道至少有一项是有效的。
{
"not": {
"items": { "not": { ... schema ... } }
}
}
如果您能够升级到 JSON Schema draft-06,则添加了 contains
关键字以简化此过程。
{
"contains": { ... schema ... }
}
蕴涵
蕴涵允许你做一些类似条件的事情。如果条件为真或约束为真(或两者都为真),则条件模式暗示约束模式。这实际上等同于说,如果条件为真,则约束条件也必须为真。
{
"anyOf": [
{ "not": { ... condition schema ... } },
{ ... constraint schema ... }
]
}
JSON Schema draft-07 添加了 if
-then
-else
关键字,试图更好地解决这种情况。我个人不喜欢这样做的方式,所以我会坚持这种事情的暗示模式,但这里是为了以防你想尝试它。
{
"if": { ... schema ... },
"then": { ... schema ... },
"else": { ... schema ... }
}
一起
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"required": ["dog"],
"properties": {
"dog": {
"type": "object",
"required": ["bananas"],
"properties": {
"bananas": { "$ref": "bananas.json" },
"thing": { "type": "object" }
}
}
},
"allOf": [
{ "$ref": "#/definitions/banana-things-implies-dog-things" }
],
"definitions": {
"banana-has-things": {
"properties": {
"dog": {
"properties": {
"bananas": {
"properties": {
"banana": {
"not": {
"items": { "not": { "required": ["things"] } }
}
}
}
}
}
}
}
},
"banana-things-implies-dog-things": {
"anyOf": [
{ "not": { "$ref": "#/definitions/banana-has-things" }},
{
"properties": {
"dog": { "required": ["things"] }
}
}
]
}
}
}