jayands
jayands

Reputation: 133

Is it possible to have a dynamically sized array in a JSON Schema whose size is based on another value

I wish to store some building data for a calculator (for an existing game) in JSON. The thing is some can be upgraded, while others cannot. They are the same type of building though. Is there a way to dynamically set the size of the array size based on the value of the maximum levels, or am I expecting too much from JSON? I intend to open-source the tool and would like to have a schema that validates for anyone that adds a JSON file to it. With the below code, Visual Studio Code is giving me a warning about how maxItems expects an integer.

{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "properties": {
    "$schema": {
      "type":"string"
    },
    "maxLevels": {
      "description": "The maximum level that this building can be upgraded to",
      "type":"integer",
      "enum": [
        1,
        5
      ]
    },
    "goldCapacity": {
      "description": "The maximum amount of gold that the building can hold.",
      "type":"array",
      "minItems": 1,
      "maxItems": {"$ref": "#/properties/maxLevels"},
      "items": {
        "type":"integer",
        "uniqueItems": true
      }
    }
  }
}

Upvotes: 2

Views: 2125

Answers (2)

esp
esp

Reputation: 7677

There is the proposal for $data reference that allows to use values from the data as the values of certain schema keywords. Using $data reference you can:

{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "properties": {
    "maxLevel": {
      "description": "The maximum level that this building can be upgraded to",
      "type":"integer",
      "minimum": 1,
      "maximum": 5
    },
    "goldCapacity": {
      "description": "The maximum amount of gold that the building can hold.",
      "type":"array",
      "minItems": 1,
      "maxItems": {"$data": "1/maxLevel"},
      "items": {
        "type":"integer",
        "uniqueItems": true
      }
    }
  }
}

In this way, the value of property "maxLevel" (that should be >= 1 and <=5) determines the maximum number of items the array "goldCapacity" can hold.

Currently only ajv (JavaScript) implements $data reference, as far as I know, and it is being considered for the inclusion in the next versions of the specification (feel free to vote for it).

Upvotes: 4

jhenderson2099
jhenderson2099

Reputation: 964

JSON (and JSON Schema) is basically a set of key/value pairs, so JSON alone has no real support to do what you want to do.

To accomplish what you want, construct the JSON with a default value for maxItems (e.g. 0), btain a reference to your JSON object and then update the value after you have your dynamic value using JavaScript:

jsonObj['maxItems'] = yourCalculatedValue;

Upvotes: 2

Related Questions