0
votes

I have been trying to get my JSON schema right. I have a boolean property based on which I have to determine the required properties. Below is my sample JSON which I want to fail the validation with item3 not present.

{
  "item1": true,
  "item2": "ABC"
}

This is the JSON which I want the validation to pass

{
  "item1": true,
  "item2": "ABC",
  "item3": {
    "subItem1": "ABC",
    "subItem2": "BAC"
  }
}

Similarly, if the item1 is false, then the validation should pass for both the above JSON's.

My JSON schema for the same is as below.

{
    "definitions": {},
    "type": "object",
    "title": "The Root Schema",
    "properties": {
        "item1": {
            "$id": "#/properties/item1",
            "type": "boolean",
            "title": "The Item1 Schema",
            "default": false,
            "examples": [
                true
            ]
        },
        "item2": {
            "$id": "#/properties/item2",
            "type": "string",
            "title": "The Item2 Schema",
            "default": "",
            "examples": [
                "ABC"
            ],
            "pattern": "^(.*)$"
        },
        "item3": {
            "$id": "#/properties/item3",
            "type": "object",
            "title": "The Item3 Schema",
            "required": [
                "subItem1",
                "subItem2"
            ],
            "properties": {
                "subItem1": {
                    "$id": "#/properties/item3/properties/subItem1",
                    "type": "string",
                    "title": "The Subitem1 Schema",
                    "default": "",
                    "examples": [
                        "AAA"
                    ],
                    "pattern": "^(.*)$"
                },
                "subItem2": {
                    "$id": "#/properties/item3/properties/subItem2",
                    "type": "string",
                    "title": "The Subitem2 Schema",
                    "default": "",
                    "examples": [
                        "BAC"
                    ],
                    "pattern": "^(.*)$"
                }
            }
        }
    },
    "required": ["item1"],
    "allOf": [{
        "if": {
            "properties": {
                "item1": {
                    "enum": [
                        true
                    ]
                }
            }
        },
        "then": {
            "required": [
                "item2",
                "item3"
            ]
        },
        "else": {
            "required": [
                "item2"
            ]
        }
    }]
}

My validation always fails.

If item1 is true, subItem2 should be required. If item1 is false, then item3 is not required, but should still validate if included.

1
What I see in your schema is, if item1 is true, then item2 and item3 are required, otherwise, only item2 is required. Is that your intent? I'm not totally clear what your goal is. Could you provide example JSON you want to validate successfully and example JSON you want to fail validation please? - Relequestual
I have added a sample JSON in the description. Just the toggle change is from true to false. @Relequestual - ZZzzZZzz
From your description of what you want in your question, it looks like you have your then and else the wrong way round, but I can't tell because your schema and what you say you want seems to be in contradiction. Hence why I asked if you could provide JSON you want to pass and fail, because currently it's unclear. - Relequestual
@RelequestualAdded the JSON samples - ZZzzZZzz
Your if/then/else block works correctly in terms of validation. The example JSON you provided that you expect to pass, fails, because you have required that item3 has a property of subItem1 and subItem2, but it does not. - Relequestual

1 Answers

1
votes

Your if/then/else block works correctly in terms of validation.

The example JSON you provided that you expect to pass, fails, because you have required that item3 has a property of subItem1 and subItem2, but it does not.

Now you've updated your example JSON that should pass to correct item3 containing subItem1 and subItem2, the validation passes with the schema you've provided.


Additionally, you want, If I understand correctly:

If item1 is true, subItem2 should be required. If item1 is false, then item3 is not required, but should still validate if included.

Move the schema that makes subItem3 required from item3 to your then clause. This will make it so subItem3 is only "required" if your if schema validates successfully (item1 is true)

{
  "definitions": {},
  "type": "object",
  "title": "The Root Schema",
  "properties": {
    "item1": {
      "$id": "#/properties/item1",
      "type": "boolean",
      "title": "The Item1 Schema",
      "default": false,
      "examples": [
        true
      ]
    },
    "item2": {
      "$id": "#/properties/item2",
      "type": "string",
      "title": "The Item2 Schema",
      "default": "",
      "examples": [
        "ABC"
      ],
      "pattern": "^(.*)$"
    },
    "item3": {
      "$id": "#/properties/item3",
      "type": "object",
      "title": "The Item3 Schema",
      "required": [
        "subItem1"
      ],
      "properties": {
        "subItem1": {
          "$id": "#/properties/item3/properties/subItem1",
          "type": "string",
          "title": "The Subitem1 Schema",
          "default": "",
          "examples": [
            "AAA"
          ],
          "pattern": "^(.*)$"
        },
        "subItem2": {
          "$id": "#/properties/item3/properties/subItem2",
          "type": "string",
          "title": "The Subitem2 Schema",
          "default": "",
          "examples": [
            "BAC"
          ],
          "pattern": "^(.*)$"
        }
      }
    }
  },
  "required": [
    "item1"
  ],
  "allOf": [
    {
      "if": {
        "properties": {
          "item1": {
            "enum": [
              true
            ]
          }
        }
      },
      "then": {
        "required": [
          "item2",
          "item3"
        ],
        "properties": {
          "item3": {
            "required": [
              "subItem2"
            ]
          }
        }
      },
      "else": {
        "required": [
          "item2"
        ]
      }
    }
  ]
}