0

Using Jsonschema draft 6, I'm trying to create a schema that conforms to the following:

  1. Properties A, B1, B2, and B3 are either numbers or null
  2. If property A is present and non-null, then properties B1, B2, and B3 must be either absent or null
  3. If any of properties B1, B2, and B3 are present and non-null, then property A must be null or absent.
  4. A, B1, B2, and B3 may all be absent

Examples of conforming documents:

{}

{"A": 1}

{"A": 1, "B2": null}

{"B1": 1}

{"B1": 1, "B2": 1, "B3": 1}

{"A": null, "B1": 1, "B2": 1, "B3": 1}

Examples of non-conforming documents:

{"A": 1, "B1": 2}

{"A": 1, "B1": null, "B2": 1}

I've seen some related questions that help but don't fully answer the question:

Here is my current schema, which only enforces constraint #1 and #4:

{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "properties": {
    "A": {"oneOf": [{"type": "null"}, {"type": "number"}],
    "B1": {"oneOf": [{"type": "null"}, {"type": "number"}],
    "B2": {"oneOf": [{"type": "null"}, {"type": "number"}],
    "B3": {"oneOf": [{"type": "null"}, {"type": "number"}]
  }
}

What is the right approach here? Am I asking for something unreasonable?

shadowtalker
  • 12,529
  • 3
  • 53
  • 96

1 Answers1

2
{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "oneOf": [
    {
      "properties": {
        "A": {"type": "number"},
        "B1": {"type": "null"},
        "B2": {"type": "null"},
        "B3": {"type": "null"}
      },
      "required": ["A"]
    },
    {
      "properties": {
        "A": {"type": "null"},
        "B1": {"type": ["number","null"]},
        "B2": {"type": ["number","null"]},
        "B3": {"type": ["number","null"]}
      },
      "anyOf": [
        {"required": ["B1"]},
        {"required": ["B2"]},
        {"required": ["B3"]}
      ]
    },
    {
      "properties": {
        "A": {"type": "null"},
        "B1": {"type": "null"},
        "B2": {"type": "null"},
        "B3": {"type": "null"}
      }
    }
  ]
}
shadowtalker
  • 12,529
  • 3
  • 53
  • 96
vearutop
  • 3,924
  • 24
  • 41
  • Note that B/C/D should have been B1/B2/B3 (I wrote the question incorrectly). – shadowtalker Feb 12 '22 at 04:47
  • I think it still doesn't quite address what I originally envisioned (either A should be a number xor at least one of B1-3 should be a number), but it seems close enough to get me going. You basically have to "expand" all valid combinations. – shadowtalker Feb 12 '22 at 04:49