JSON Schema if-else condition complex scenario

馋奶兔 提交于 2019-12-11 18:23:51

问题


    {
        "policyHolder": {
            "fullName": "A"
        },
        "traveller": [
            {
                "fullName": "B",
                "relationship": "Spouse"
            },
            {
                "fullName": "A",
                "relationship": "My Self"
            }
        ]
    }

In above json, I want to validate that

  • if "relationship" = "My Self" then fullName must match the fullName in policyHolder
  • A field relationship must exist in traveller array, else json is invalid

I have tried to create a json schema with if-else, allOf, etc. but nothing works which can do these validations but not able to. Please help!!

Schema:

{
    "type": "object",
    "required": [
        "policyHolder",
        "traveller",
    ],
    "properties": {
        "policyHolder": {
            "$id": "#/properties/policyHolder",
            "type": "object",
            "required": [
                "fullName"
            ],
            "properties": {
                "fullName": {
                    "$id": "#/properties/policyHolder/properties/fullName",
                    "type": "string",
                }
            }
        },
        "traveller": {
            "$id": "#/properties/traveller",
            "type": "array",
            "minItems": 1,
            "items": {
                "$id": "#/properties/traveller/items",
                "type": "object",
                "properties": {
                    "fullName": {
                        "$ref": "#/properties/policyHolder/properties/fullName"
                    },
                    "relationship": {
                        "$id": "#/properties/traveller/items/properties/relationship",
                        "type": "string",
                    }
                },
                "required": [
                    "fullName",
                    "relationship"
                ],
                }
            }
        }
    }```


回答1:


It's your first requirement that you're going to have the most trouble with. JSON Schema doesn't support validation of data against data elsewhere in the instance. It's a highly discussed topic, but nothing has been adopted yet. I suggest you verify this with a little code.

For the second, I would suggest you extract some of your subschemas into definitions rather than trying to muck about with IDs. IDs are typically more beneficial if you're referencing them from other documents or if you use short (like single-word) IDs. Defining the ID as its location in the document is redundant; most processors will handle this automatically.

{
  "type": "object",
  "required": [
    "policyHolder",
    "traveller",
  ],
  "definitions": {
    "person": {
      "type": "object"
      "properties": {
        "fullName": {"type": "string"}
      },
      "required": ["fullName"]
    },
    "relationship": { "enum": [ ... ] }   // list possible relationships
  },
  "properties": {
    "policyHolder": { "$ref": "#/definitions/person" },
    "traveller": {
      "type": "array",
      "minItems": 1,
      "items": {
        "allOf": [
          { "$ref": "#/definitions/person" },
          {
            "properties": {
              "relationship": { "$ref": "#/definitions/relationship" }
            },
            "required": ["relationship"]
          }
        ]
      }
    }
  }
}

(I extracted the relationship into its own enum definition, but this is really optional. You can leave it inline, or even an unrestricted string if you don't have a defined set of relationships.)




回答2:


This can't currently be done with JSON Schema. All JSON Schema keywords can only operate on one value at a time. There's a proposal for adding a $data keyword that would enable doing this kind of validation, but I don't think it's likely to be adopted. $data would work like $ref except it references the JSON being validated rather than referencing the schema.

Here's what how you would solve your problem with $data.

{
  "type": "object",
  "properties": {
    "policyHolder": {
      "type": "object",
      "properties": {
        "fullName": { "type": "string" }
      }
    },
    "traveler": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "fullName": { "type": "string" },
          "relationship": { "type": "string" }
        },
        "if": {
          "properties": {
            "relationship": { "const": "My Self" }
          }
        },
        "then": {
          "properties": {
            "fullName": { "const": { "$data": "#/policyHolder/fullName" } }
          }
        }
      }
    }
  }
}

Without $data, you will have to do this validation in code or change your data structure so that it isn't necessary.



来源:https://stackoverflow.com/questions/55430680/json-schema-if-else-condition-complex-scenario

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!