0

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.

9
  • 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? Commented Apr 25, 2019 at 8:09
  • I have added a sample JSON in the description. Just the toggle change is from true to false. @Relequestual Commented Apr 25, 2019 at 12:48
  • 1
    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. Commented Apr 25, 2019 at 12:51
  • @RelequestualAdded the JSON samples Commented Apr 25, 2019 at 13:16
  • 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. Commented Apr 25, 2019 at 13:43

1 Answer 1

1

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"
        ]
      }
    }
  ]
}
Sign up to request clarification or add additional context in comments.

10 Comments

If Item3 is required then all the subItems as required. Else, the requirement under the Item3 should be nullified.
This is currently what happens. In your example JSON you expect to pass, if you remove item3, validation fails because item1` is true, which triggers the then block of your if block, which then makes item3 required, and therefore you fail validation.
If you have additional JSON pass / fail examples which are not working as you expect, please share them, and test using jsonschemavalidator.net
Removing either of the subitems causes validation to fail. Isn't that what you expect?
OK! Solved. Will update your question, followed by my answer.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.