use*_*192 6 schema json jsonschema json-schema-validator
我有一个 json 对象,如:
{
"session": {
"session_id": "A",
"start_timestamp": 1535619633301
},
"sdk": {
"name": "android",
"version": "21"
}
}
Run Code Online (Sandbox Code Playgroud)
该sdk name可以是android or ios。并且session_id基于name fieldin sdk json。我写了一个json schemausing 条件语句(使用草案 7)如下:
但它以一种意想不到的方式工作:
{
"$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"
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以下面的 JSON 传递:
{
"session": {
"session_id": "A",
"start_timestamp": 1535619633301
},
"sdk": {
"name": "ios",
"version": "21"
}
}
Run Code Online (Sandbox Code Playgroud)
但这失败了:
{
"session": {
"session_id": "B",
"start_timestamp": 1535619633301
},
"sdk": {
"name": "android",
"version": "21"
}
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下吗?..即使这样通过:
{
"session": {
"session_id": "A",
"start_timestamp": 1535619633301
},
"sdk": {
"name": "android",
"version": "21"
}
}
Run Code Online (Sandbox Code Playgroud)
我认为您遇到了与此问题类似的问题。
@Relequestual 是正确的,因为您需要在标注properties周围使用关键字SDK。但是对于你想做的事情,你需要重新组织。
子模式仅在实例中的级别上运行,而不是在根上运行。
考虑一个包含 aone和一个two属性的简单 JSON 对象实例的模式:
{
"properties": {
"one": {
"enum": ["yes", "no", "maybe"]
},
"two": {
"if": {
"properties": {
"one": {"const": "yes"}
}
},
"then": {
... // do some assertions on the two property here
},
"else": {
...
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
所述if的下关键字two属性只能考虑实例的下方的部分two属性(即two“S值)。它没有查看实例的根,因此它根本看不到该one属性。
为了让two属性subschema 下的subschema 可以看到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
}
}
Run Code Online (Sandbox Code Playgroud)
对于 的两个可能值one,这是相当不错的。即使三个可能的值也不错。但是,随着 的可能值的one增加,ifs的嵌套也会增加,这会使您的架构难以阅读(并且可能使验证变慢)。
代替使用的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
}
}
]
}
Run Code Online (Sandbox Code Playgroud)
在我看来,这要干净得多。
希望该解释可以帮助您重建架构以允许其他实例通过。
| 归档时间: |
|
| 查看次数: |
2665 次 |
| 最近记录: |