我有一个像json对象:
{
"session": {
"session_id": "A",
"start_timestamp": 1535619633301
},
"sdk": {
"name": "android",
"version": "21"
}
}
sdk name
可以是android or ios
。并且session_id
基于name field
中的sdk json
。我已经使用条件语句(使用草稿7)编写了json schema
,如下所示:但是它以一种意想不到的方式工作:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/Base",
"definitions": {
"Base": {
"type": "object",
"additionalProperties": false,
"properties": {
"session": {
"$ref": "#/definitions/Session"
},
"sdk": {
"$ref": "#/definitions/SDK"
}
},
"title": "Base"
},
"Session": {
"type": "object",
"additionalProperties": false,
"properties": {
"start_timestamp": {
"type": "integer",
"minimum": 0
},
"session_id": {
"type": "string",
"if": {
"SDK": {
"properties": {
"name": {
"enum": "ios"
}
}
}
},
"then": {
"pattern": "A"
},
"else": {
"pattern": "B"
}
}
},
"required": [
"session_id",
"start_timestamp"
],
"title": "Session"
},
"SDK": {
"type": "object",
"additionalProperties": false,
"properties": {
"version": {
"type": "string"
},
"name": {
"type": "string",
"enum": [
"ios",
"android"
]
}
},
"required": [
"name",
"version"
],
"title": "SDK"
}
}
}
因此,以下JSON通过:
{
"session": {
"session_id": "A",
"start_timestamp": 1535619633301
},
"sdk": {
"name": "ios",
"version": "21"
}
}
但这失败了:
{
"session": {
"session_id": "B",
"start_timestamp": 1535619633301
},
"sdk": {
"name": "android",
"version": "21"
}
}
有人可以解释吗?
{
"session": {
"session_id": "A",
"start_timestamp": 1535619633301
},
"sdk": {
"name": "android",
"version": "21"
}
}
最佳答案
我认为您遇到了与this question类似的问题。
@Relequestual是正确的,因为您需要在properties
标注周围加上SDK
关键字。但是对于您想做的事情,您需要进行重组。
子模式仅在实例上按其级别运行,而不在根上运行。
对于包含one
和two
属性的简单JSON对象实例,请考虑以下模式:
{
"properties": {
"one": {
"enum": ["yes", "no", "maybe"]
},
"two": {
"if": {
"properties": {
"one": {"const": "yes"}
}
},
"then": {
... // do some assertions on the two property here
},
"else": {
...
}
}
}
}
if
属性下的two
关键字只能考虑two
属性下的实例部分(即two
的值)。它没有查看实例的根,因此根本看不到one
属性。为了使
two
属性子模式下的子模式可以在实例中看到one
属性,必须将if
移到properties
关键字之外。{
"if": {
"properties": {
"one": {"const" : "yes"}
}
},
"then": {
... // do some assertions on the two property here
},
"else": {
... // assert two here, or have another if/then/else structure to test the one property some more
}
}
对于
one
的两个可能值,这非常好。甚至三个可能的值也不错。但是,随着one
可能值的增加,if
的嵌套也会增加,这会使您的架构难以阅读(并可能使验证变慢)。我建议不要使用
if
/then
/else
构造,而建议使用anyOf
或oneOf
,其中每个子模式都代表实例的有效状态(给定one
的值各不相同)。{
"oneOf": [
{
"properties": {
"one": {"const": "yes"},
"two": ... // do some assertions on the two property here
}
},
{
"properties": {
"one": {"const": "no"},
"two": ... // do some assertions on the two property here
}
},
{
"properties": {
"one": {"const": "maybe"},
"two": ... // do some assertions on the two property here
}
}
]
}
我认为这要干净得多。
希望这种解释可以帮助您重构架构以允许其他实例通过。
关于json - 在基于另一个架构对象的json架构上使用条件语句,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55225212/