【问题标题】:Validate Json schema based on the value specified for a property根据为属性指定的值验证 Json 架构
【发布时间】:2019-06-18 06:31:38
【问题描述】:

我有一个 Json 请求,其中包含以下数据和相应的 json 架构

有了这个要求,我想根据模式做一些需要的字段

假设如果mode为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 架构中进行此类验证?

【问题讨论】:

    标签: json jsonschema json-schema-validator


    【解决方案1】:

    您想要的是一个oneOf,其中每个子模式为每个obj* 属性提供一个有效状态。每个状态都是这样的:

    {
      "properties": {
        "mode": {"const": 1},
        "obj1": {"required": ["a","b"]},
        "obj3": {"required": ["x"]}
      }
    }
    

    为您在问题中列出的每个状态创建其中一个,并将它们全部放入位于根目录的oneOf

    可以使用if/then/else 执行此操作,但对于这种情况,我更喜欢oneOf 以避免嵌套。


    另外,我注意到中间有很多多余的$ids,它们只是指定它们在架构中的位置。你想要一个根,但你不需要其他的。实现可以轻松地计算出这些类型的基于位置的引用。

    【讨论】:

    • 感谢您的回复@gregsdennis。尽管我理解您建议的方法,但我想澄清这是否正是您的意思。你可以看看我发布的架构作为编辑吗?
    • 是的,这看起来适合模式 1 和 2。每个模式都需要一个条目。
    • 完美。再次感谢@gregsdennis
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-03
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    相关资源
    最近更新 更多