15

Consider the following JSON :

 {
      "1234abcd" : {
                     "model" : "civic"
                      "made" : "toyota"
                      "year" : "2014"
                     }

 }

consider another JSON :

 {
      "efgh56789" : {
                     "model" : "civic"
                      "made" : "toyota"
                      "year" : "2014"
                     }

 }

the outermost alphanumeric key will vary and required, if the key was fixed; let's say "identifier" then the schema was straightforward, however since the key-name is variable, we have to use patternProperties, how can I come up with a schema that captures these requirement for the outermost key:

  1. property name (key) is variable
  2. required
  3. alphanumeric lowercase

using json-schema : https://github.com/ruby-json-schema/json-schema in ruby.

dreftymac
  • 31,404
  • 26
  • 119
  • 182
EasyQuestions
  • 327
  • 1
  • 10
  • 23

2 Answers2

28

The best you can do to require properties when those properties are variable is to use minProperties and maxProperties. If you want to say there must be one and only one of these alphanumeric keys in your object, you can use the following schema. If you want to say there has to be at least one, you could just leave out maxProperties.

{
  "type": "object",
  "patternProperties": {
    "^[a-z0-9]+$": {
      "type": "object",
      "properties": {
        "model": { "type": "string" },
        "make": { "type": "string" },
        "year": { "type": "string" }
      },
      "required": ["model", "make", "year"]
    }
  },
  "additionalProperties": false,
  "maxProperties": 1,
  "minProperties": 1
}
Jason Desrosiers
  • 22,479
  • 5
  • 47
  • 53
15

You may have to change the regular expression to fit your valid keys:

{
"patternProperties": {
    "^[a-zA-Z0-9]*$":{
        "properties": {
              "model":{"type":"string"},
              "made":{"type":"string"},
              "year":{"type":"string"}
         }
    }
},
"additionalProperties":false
}
jruizaranguren
  • 12,679
  • 7
  • 55
  • 73
  • the regexp should be this : `"^[a-z0-9]*$"`, since we are only interested in lowercase keys. but will this make it required in schema v4? – EasyQuestions Jun 11 '15 at 20:00
  • The provided schema enforces that the key of every new defined property in the top level must satisfy the regexp. I don't understand what you mean by required in this context. – jruizaranguren Jun 12 '15 at 06:36
  • i simplified the case, but if I had more properties in the top level that were fixed and didn't need regexp matching, how could I make sure that only the pattern properties is required (it must be there) and not the others. anyways this is good to get me going, thank you. – EasyQuestions Jun 12 '15 at 19:18
  • You can make required just regular explicitly defined keys. Required must be an array with explicit string keys. You can not make required a key that is not known at design time (the pattern properties may be from zero to infinite key values). Anyway, you will have to remove additionalProperties:false – jruizaranguren Jun 12 '15 at 21:10
  • Regexp allows empty string as key. Also s/toyota/honda/ or /civic/corolla/ :) – Denis Barmenkov Nov 04 '20 at 11:52