Galg
Galg

Reputation: 17

json schema mixing optional patternproperties with ref

I'm new to json schema. I tried some complex mix and it doesn't work like I expected. I have the following json:

{
  "aaa": {
    "Type": "Type1",
    "prop1": "val3"
  },
  "bbb": {
    "Type": "Type1",
    "prop2": "val4"
  }
}

The Idea is that the json contains jsons of objects with Type1 that have a variable key (property?) name and may contain another object (Type2 or Type 3) in it and the only mandatory property is Type with the value Type1

I tried to use the following schema to validate the json above:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "definitions": {
    "Type1": {
      "type": "object",
      "properties": {
        "Type": {
          "const": "Type1"
        },
        "prop1": {
          "type": "string"
        },
        "prop2": {
          "type": "string"
        }
      },
      "patternProperties": {
        "^[a-zA-Z0-9_]+$": {
          "oneOf": [
            {
              "$ref": "#/definitions/Type2"
            },
            {
              "$ref": "#/definitions/Type3"
            }
          ]
        }
      },
      "required": [
        "Type"
      ],
      "additionalProperties": false
    },
    "Type2": {
      "type": "object",
      "properties": {
        "PropArr": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "Type": {
          "const": "Type2"
        }
      },
      "required": [
        "PropArr",
        "Type"
      ],
      "additionalProperties": false
    },
    "Type3": {
      "type": "object",
      "properties": {
        "Prop": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "Type": {
          "const": "Type3"
        }
      },
      "required": [
        "Prop",
        "Type"
      ],
      "additionalProperties": false
    }
  },
  "patternProperties": {
    "^[a-zA-Z0-9_]+$": {
      "type": "object",
      "oneOf": [
        {
          "$ref": "#/definitions/Type1"
        }
      ]
    }
  },
  "minProperties": 1,
  "additionalProperties": false
}

however I fail to validate this json because it doesn't contain type2 or type3 for type1 objects. Is specifying "oneof" for pattern properties (in Type1) implies that it must contain the patterned property? is there a way to make that object optional in the schema?

Upvotes: 2

Views: 2379

Answers (1)

Relequestual
Relequestual

Reputation: 12335

There are few issues and missconceptions here. That's OK.

I put your schema and JSON instance into an online validator. I find this super helpful to get immediate feedback as to why validation fails.

The approach you want to take is right, but the implementation is slightly off.

Starting at patternProperties after all of your definition, you've stated that each property (that matches the pattern) must have a value that is an object. Good. The object must be Type1 which you've referenced correctly.

In your definition of Type1, you've used properties and patternProperties. patternProperties is being applied to the properties you've already specified in properties because it doesn't exclude those found in other "properties" based keywords. additionalProperties however, which may be a schema, only applies to those properties which haven't already been covered by properties and patternProperties.

Validation with "additionalProperties" applies only to the child values of instance names that do not match any names in "properties", and do not match any regular expression in "patternProperties".

Draft-7 validations additionalProperties

Hopefully this explanation and the link to the online validator (which provides helpful validation failure messages) will allow you to progress with your schema. It's a little difficult to give you a corrected schema when I can't see more possible instance json data.

Upvotes: 1

Related Questions