json - 根据为属性指定的值验证 Json 架构
问题描述
我有一个 Json 请求,其中包含以下数据和相应的 json 模式
有了这个请求,我想根据模式制作一些需要的字段
假设如果模式为 1,那么我希望 obj1 中的字段 a 和 b 是必需的,并且 obj3 中的字段 x 是必需的。现在,如果模式为 2,我希望 obj2 中的字段 p、q 和 r 是必需的,obj1 中的字段 a 和 c 是必需的,obj3 中的字段 y 是必需的。接下来如果模式是3,我只需要字段a和c
json请求
{
"mode": "1",
"obj1": {
"a": 12,
"b": "test",
"c": "18 June 2019"
},
"obj2": {
"p": 100,
"q": "new",
"r": "19 June 2019",
"s" : "test2"
},
"obj3": {
"x": 12,
"y": "test3"
}
}
**Json schema**
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/root.json",
"type": "object",
"properties": {
"mode": {
"$id": "#/properties/mode",
"type": "string",
"examples": [
"1"
]
},
"obj1": {
"$id": "#/properties/obj1",
"type": "object",
"title": "The Obj 1 Schema",
"properties": {
"a": {
"$id": "#/properties/obj1/properties/a",
"type": "integer",
"examples": [
12
]
},
"b": {
"$id": "#/properties/obj1/properties/b",
"type": "string",
"examples": [
"test"
]
},
"c": {
"$id": "#/properties/obj1/properties/c",
"type": "string",
"examples": [
"18 June 2019"
]
}
}
},
"obj 2": {
"$id": "#/properties/obj2",
"type": "object",
"title": "The Obj 2 Schema",
"properties": {
"p": {
"$id": "#/properties/obj2/properties/p",
"type": "integer",
"examples": [
100
]
},
"q": {
"$id": "#/properties/obj2/properties/q",
"type": "string",
"examples": [
"new"
]
},
"r": {
"$id": "#/properties/obj2/properties/r",
"type": "string",
"examples": [
"19 June 2019"
]
},
"s": {
"$id": "#/properties/obj2/properties/s",
"type": "string",
"examples": [
"test2"
]
}
}
},
"obj 3": {
"$id": "#/properties/obj3",
"type": "object",
"title": "The Obj 3 Schema",
"properties": {
"x": {
"$id": "#/properties/obj3/properties/x",
"type": "integer",
"examples": [
12
]
},
"y": {
"$id": "#/properties/obj3/properties/y",
"type": "string",
"examples": [
"test3"
]
}
}
}
}
}
编辑 - 根据@gregsdennis 的建议更改架构以进行验证
JSON 架构
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/root.json",
"type": "object",
"properties": {
"mode": {
"$id": "#/properties/mode",
"type": "string",
"examples": [
"1"
]
},
"obj1": {
"$id": "#/properties/obj1",
"type": "object",
"title": "The Obj 1 Schema",
"properties": {
"a": {
"type": "integer",
"examples": [
12
]
},
"b": {
"type": "string",
"examples": [
"test"
]
},
"c": {
"type": "string",
"examples": [
"18 June 2019"
]
}
}
},
"obj 2": {
"$id": "#/properties/obj2",
"type": "object",
"title": "The Obj 2 Schema",
"properties": {
"p": {
"type": "integer",
"examples": [
100
]
},
"q": {
"type": "string",
"examples": [
"new"
]
},
"r": {
"type": "string",
"examples": [
"19 June 2019"
]
},
"s": {
"type": "string",
"examples": [
"test2"
]
}
}
},
"obj 3": {
"$id": "#/properties/obj3",
"type": "object",
"title": "The Obj 3 Schema",
"properties": {
"x": {
"type": "integer",
"examples": [
12
]
},
"y": {
"type": "string",
"examples": [
"test3"
]
}
}
}
},
"oneOf": [
{
"properties": {
"mode": {"const": 1},
"obj1": {"required": ["a","b"]},
"obj3": {"required": ["x"]}
}
},
{
"properties": {
"mode": {"const": 2},
"obj2": {"required": ["p","q","r"]},
"obj1": {"required": ["a","c"]},
"obj3": {"required": ["y"]}
}
}
]
}
因此,简而言之,无论我有多少模式、字段或对象,我都希望在给定时间为特定模式只需要来自不同对象的几个选定字段。任何人都可以提出任何解决方案来实现这一目标吗?是否可以在 json 模式中进行此类验证?
解决方案
您想要的是oneOf
每个子模式为每个obj*
属性提供有效状态的位置。每个状态都是这样的:
{
"properties": {
"mode": {"const": 1},
"obj1": {"required": ["a","b"]},
"obj3": {"required": ["x"]}
}
}
为您在问题中列出的每个状态创建其中一个,并将它们全部放入oneOf
根中。
您可以if
使用/ then
/来执行此操作else
,但对于这种情况,我希望oneOf
避免嵌套。
另外,我注意到$id
中间有很多多余的 s 只是指定它们在模式中的位置。你想要一个根,但你不需要其他的。实现可以轻松地计算出这些类型的基于位置的引用。
推荐阅读
- sql-server - 用户在尝试连接到 Azure SQL 数据库时收到错误号 18456
- python - 将十进制转换为二进制(Python)
- node.js - 为什么我的 NodeJS lambda 函数在一次调用时执行多次?
- microsoft-graph-api - 如何将特定 Graph API 权限范围限定为特定用户或邮箱
- mpi - #pragma acc host_data use_device 的问题
- matlab - 在并行模式下运行测试时如何解决缺少的 simulink 仿真工件问题?
- python - 如何使用 Python argparse 模块打印自定义消息
- c# - 如何将带分隔符的字符串拆分为 5 列
- icloud - 如何恢复 Icloud 驱动器中以前版本的文件夹?
- c# - 如何加快ListView的处置