Search code examples
jsonjsonschema

How to allow for multiple instances of an object in JSON schema


I have a json file where I want the schema to accept multiple instances of the same object. Here is an example json file.

{
    "component_name1": {
        "codes": {
            "if_exists": "SSNM",
            "if_does_not": "MMNS"
        },
        "range": {
            "lower": 0.0,
            "upper": 1.0
        }
  },
    "component_name2": {
        "codes": {
            "if_exists": "SJHS",
            "if_does_not": "OTTF"
        },
        "range": {
            "lower": 12.3,
            "upper": 45.6
        }
    }
}

I've found valid schemas that hard code component_name1 and component_name2 (like the one below), but I don't want those to be hard coded. Component_name1 and component_name2 are the same type of object. I want a schema that will allow for any number of these objects. If a user of my schema needs component_name3, component_name4, component_name5, and so on, I want the schema to accept that. How can I do that?

Note: this is the current schema I have that I DON'T want.

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "component_name1": {
      "type": "object",
      "properties": {
        "codes": {
          "type": "object",
          "properties": {
            "if_exists": {
              "type": "string"
            },
            "if_does_not": {
              "type": "string"
            }
          },
        },
        "range": {
          "type": "object",
          "properties": {
            "lower": {
              "type": "number"
            },
            "upper": {
              "type": "number"
            }
          },
        }
      },
    },
      
    "component_name2": {
      "type": "object",
      "properties": {
        "codes": {
          "type": "object",
          "properties": {
            "if_exists": {
              "type": "string"
            },
            "if_does_not": {
              "type": "string"
            }
          },
        },
        "range": {
          "type": "object",
          "properties": {
            "lower": {
              "type": "number"
            },
            "upper": {
              "type": "number"
            }
          },
        }
      },
    }
  },
}

I would love to have something like this, but I know the example below won't allow for the multiple instances of the object I want.

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "ANY COMPONENT NAME": {
      "type": "object",
      "properties": {
        "codes": {
          "type": "object",
          "properties": {
            "if_exists": {
              "type": "string"
            },
            "if_does_not": {
              "type": "string"
            }
          },
        },
        "range": {
          "type": "object",
          "properties": {
            "lower": {
              "type": "number"
            },
            "upper": {
              "type": "number"
            }
          },
        }
      },
    },
  }
      
}

I've tried using regular expressions where component_name1 is to allow for any string like (^.*$). Regex didn't seem to be recognized in json schema.

You know how in regex you can declare x number of occurances? Like I can do ^Hm*$, and it could be "Hm" or "Hmmmmmm" or "Hmm". That's sort of the idea I want to do. I want to allow for one or more of this object without hard coding all instances of the object.


Solution

  • you can create dynamic properties with a schema definition applied to them.

    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "object",
      "additionalProperties": {
        "$ref": "#/definitions/component_type"
      },
      "definitions": {
        "component_type": {
          "type": "object",
          "properties": {
            "codes": {
              "type": "object",
              "properties": {
                "if_exists": {
                  "type": "string"
                },
                "if_does_not": {
                  "type": "string"
                }
              }
            },
            "range": {
              "type": "object",
              "properties": {
                "lower": {
                  "type": "number"
                },
                "upper": {
                  "type": "number"
                }
              }
            }
          }
        }
      }
    }