'How to different constraint Settings for objects at the same level in jsonschema maybe some of list mybe either-or?

I need to write to jsonschem for a json data. #First json data

{
  "name1": "name_string",
  "name2": "name_string",
  "name3": "name_string",
  "name4": "naem_string",
  "home1": "string",
  "home2": "string",
  "age": "number"
}

In the json data which require some of ["name1", "name2", "name3", "name4"] and should be one of ["home1", "home2"] and the age is optional. for example:

{
  "name1": "name_string",
  "name4": "name_string",
  "home1": "string",
  "age": 16
}  #this json data is satisfactory.

{
  "name1": "name_string",
  "name4": "name_string",
  "home2": "string",
  "age": 18
} #this json data is satisfactory.

{
  "home2": "string",
  "age": 18
} # this json data in not OK, beacuse miss `name` in the list `["name1", "name2", "name3", "name4"]`.

{
  "name1": "name_string",
  "name4": "name_string",
  "home1": "string",
  "home2": "string",
  "age": 18
} #this json data is not OK, beacuse `home1` and `home2` should only one in the data.

{
  "name1": "name_string",
  "name4": "name_string",
  "age": 18
} #this json data is not OK, beacuse `home1` and `home2` should one in the data.

I have try to add attributes above name. like this #Second json data

{
   "name":{
    "name1": "name_string",
    "name2": "name_string",
    "name3": "name_string",
    "name4": "naem_string",
    },
   "home":{
    "home1": "string",
    "hone2": "string"
    }
}

For the second json data I write json schema as fellow:

{
  "type": "object",
  "required": [],
  "minProperties":1,
  "maxProperties":3,
  "propertyNames": {"enum": ["name1","name2","name3","name4"]},
  "properties": {
    "name": {
      "type": "object",
      "required": [],
      "properties": {
        "name1": {
          "type": "string"
        },
        "name2": {
          "type": "string"
        },
        "name3": {
          "type": "string"
        }
      }
    },
    "home": {
      "type": "object",
      "required": [],
      "minProperties":1,
      "maxProperties":1,
      "oneOf":[
           {"required":["home1"]},
           {"required":["home2"]}
         ],
      "properties": {
        "home1": {
          "type": "string"
        },
        "home2": {
          "type": "string"
        }
      }
    }
  }
}

but I don't know how to wirte a json schema for sceond json data which meets my need, which can require some of list ["name1","name2","name3","name4"] and one of list for ["home1", "home2"], because there are in same level now.



Solution 1:[1]

The key here is to understand applicability.

You can use the *Of applicator keywords to apply subschemas to the same instance location, combining and modifying the validation result of the subschemas.

In practice, here's what I'd suggest for your JSON Schema. (Working demo: https://jsonschema.dev/s/G8Qo6)

{
  "type": "object",
  "allOf": [
    {
      "$comment": "for name[1-4]. At least one `nameN`.",
      "anyOf": [
        {"required":["name1"]},
        {"required":["name2"]},
        {"required":["name3"]},
        {"required":["name4"]}
      ]
    },
    {
      "$comment": "for home[1-2]. One of (exclusive or) `homeN` only.",
      "oneOf":[
        {"required":["home1"]},
        {"required":["home2"]}
      ]
    }
  ],
  "properties": {
    "name1": { "type": "string" },
    "name2": { "type": "string" },
    "name3": { "type": "string" },
    "name4": { "type": "string" },
    "home1": { "type": "string" },
    "home2": { "type": "string" },
    "age": { "type": "number" }
  },
  "additionalProperties": false
}

You can separate the concerns of the object's keys and the object's values.

You could move the oneOf and anyOf to the schema root, but it's segmented like this for illustrative purposes.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ether