8

For the following json string :

{
    "abc" : 123,
    "def" : 345
}

The following schema considers it valid :

{
    "$schema": "http://json-schema.org/draft-03/schema#",
    "title": "My Schema",
    "description": "Blah",
    "type": "object",
    "patternProperties": {
        ".+": {
            "type": "number"
        }
    }
}

However, changing the the patternProperties to properties still considers it valid. What then, is the difference between these 2 tags?

4 Answers4

7

For the schema above all properties should be number. This data is invalid:

{ a: 'a' }

If you replace patternProperties with properties only property '.+' should be number. All other properties can be anything. This would be invalid:

{ '.+': 'a' }

This would be valid:

{ a: 'a' }
esp
  • 7,314
  • 6
  • 49
  • 79
  • What do you mean when you say all other properties can be anything? Does that mean none of the other properties will be validated? how do i restrict that? – Ashwin Lakshmanan Jun 25 '15 at 06:34
  • In case of 'patternProperties' all the properties matching the patterns in keys will be validated. If you use 'properties' only properties equal to the keys will be validated. So if you want to validate properties matching pattern, you should use 'patternProperties'. If you want to validate all properties against the same schema it is better to use 'additionalProperties'. Your schema can be ```{"type": "object", "additionalProperties": {"type": "number"}}``` - it will require that all properties are numbers. Using patternProperties for this case is inefficient. – esp Jun 25 '15 at 10:03
  • okay, so properties will only validate fields when have the exact same matching key. patternProperties will match all keys that fall under that pattern. additionalProperties validates all the other properties in the file not already convered by properties or patternProperties. Is my understanding correct? 2 questions here 1. Why is patternProperties inefficient for this case? 2. Isnt there a way to specify that my file will contain this property only? As in, fail if the file contains any other property not mentioned here? – Ashwin Lakshmanan Jun 26 '15 at 09:42
  • That is correct. One addition is that "patternProperties" will also validate properties that are mentioned in "properties", as long as the pattern matches. 1. Because your pattern will match all properties anyway (apart from the empty one of course). So in this case matching is unnecessary. 2. "additionalProperties": false – esp Jun 26 '15 at 20:41
2

The properties (key-value pairs) on an object are defined using the properties keyword. The value of properties is an object, where each key is the name of a property and each value is a JSON schema used to validate that property.

additionalProperties can restrict the object so that it either has no additional properties that weren’t explicitly listed, or it can specify a schema for any additional properties on the object. Sometimes that isn’t enough, and you may want to restrict the names of the extra properties, or you may want to say that, given a particular kind of name, the value should match a particular schema. That’s where patternProperties comes in: it is a new keyword that maps from regular expressions to schemas. If an additional property matches a given regular expression, it must also validate against the corresponding schema.

Note: When defining the regular expressions, it’s important to note that the expression may match anywhere within the property name. For example, the regular expression "p" will match any property name with a p in it, such as "apple", not just a property whose name is simply "p". It’s therefore usually less confusing to surround the regular expression in ^...$, for example, "^p$".

for further reference --http://spacetelescope.github.io/understanding-json-schema/reference/object.html

Kandy
  • 673
  • 9
  • 21
  • The first paragraph directly contradicts the example i have given : When i change the patternProperties keyword to properties without changing the rest of the schema, it still works, meaning the properties keyword is also processing the regular expression. – Ashwin Lakshmanan Jun 19 '15 at 11:09
  • may be due to your properties keyword treated your regex as a property having value type as number only and you are providing a number that why its accepted your value. I am not sure.. – Kandy Jun 19 '15 at 12:09
0

Semantic of properties:

  • If you declare a property with a key included in properties, it must satisfy the schema declared in properties.

Semantic of patternProperties:

  • If you declare a property and the key satisfy the regex defined in patternProperties, it must satisfy the schema declared in patternProperties.

According to the docs, properties priority is higher than patternProperties, meaning that the schema is validated against patternProperties only if there has not been a match in properties first.

jruizaranguren
  • 12,679
  • 7
  • 55
  • 73
0

A JSON object is composed of key: value pairs. In a schema the key correspond to a property and for the value part we define it's data type and some other constratints.

Therefore the following schema

{ 
 "type": "object",
 "properties": {
    "a": {
        "type": "number"
    }
}

will only validate a JSON object with the key "a" that is an object like {"a": 1}. An object like {"b": 1} won't validate

Meanwhile the patternProperties tag allows you to define properties using a regex. In this you basically don't need to define all the properties one after another. A use case of this will be for example if you don't know the name of the keys in advance but you know that all the keys match a certain pattern.

Hence your schema can validate {"a": 1} as well as {"b": 1}

The patternProperties tag does the job of an additionalProperties tag but in addition allows you to have a finer control on the keys

Hippolyte Fayol
  • 526
  • 1
  • 5
  • 14