根据为 属性 指定的值验证 Json 架构

Validate Json schema based on the value specified for a property

我有一个 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,它们只是指定它们在架构中的位置。你想要根部的一个,但你不需要其他的。实现可以简单地计算出这些类型的 location-based 引用。