1

I have the following schema, and what I am trying to accomplish, is where I can have one or more of the following:

  • a1 but not a2 and vise versa
  • b1 but not b2 and vise versa
  • c1 but not c2 and vise versa

Here is the json schema that I am trying but it doesn't work:

{
    "type": "object",
    "properties": {
        "action": {
            "type": "object",
            "properties": {
                "a1": {},
                "a2": {},
                "b1": {},
                "b2": {},
                "c1": {},
                "c2": {}    
            },
            "anyOf": [
                {
                    "oneOf": [
                        {"required": ["a1"]},
                        {"required": ["a2"]}
                    ]
                },
                {
                    "oneOf": [
                        {"required": ["b1"]},
                        {"required": ["b2"]}
                    ]
                },
                {
                    "oneOf": [
                        {"required": ["c1"]},
                        {"required": ["c2"]}
                    ]
                }
            ]
        }
    }                  
}

It is telling me that the following is valid json:

{
    "action": {
        "a1": {},
        "b1": {},
        "b2": {}
    }    
}

This shouldn't be valid because both b1 and b2 are set.

Get Off My Lawn
  • 34,175
  • 38
  • 176
  • 338

1 Answers1

0

I think the best way to do it is with dependencies. This says, if "a1" is present, then "a2" can not be present (etc. for b and c).

{
  "type": "object",
  "dependencies": {
    "a1": { "not": { "required": ["a2"] } },
    "b1": { "not": { "required": ["b2"] } },
    "c1": { "not": { "required": ["c2"] } }
  }
}

EDIT: Full Schema

{
    "type": "object",
    "properties": {
        "action": {
            "type": "object",
            "properties": {
                "a1": {},
                "a2": {},
                "b1": {},
                "b2": {},
                "c1": {},
                "c2": {}    
            },
            "dependencies": {
                "a1": { "not": { "required": ["a2"] } },
                "b1": { "not": { "required": ["b2"] } },
                "c1": { "not": { "required": ["c2"] } }
            }
        }
    }                  
}

Note that declaring properties in this case is meaningless because they are empty schemas. I left it in to avoid confusion.

Jason Desrosiers
  • 22,479
  • 5
  • 47
  • 53
  • I have tried this, and I am not able to add `a1` and `a2`, but I can add `b1` and `b2`, I can also add `c1` and `c2`. – Get Off My Lawn Sep 28 '16 at 14:33
  • It works. Either the validator you are working with has a bug or you didn't incorporate into your schema correctly. I may have simplified too much and it wasn't clear where to put this. I'll include the full schema just to make sure. – Jason Desrosiers Sep 28 '16 at 21:48
  • I do not think it is the editor. The schema allows for `a1` and `a2` to be present. Not required does not mean forbidden. http://stackoverflow.com/questions/24023536/json-schema-how-do-i-require-one-field-or-another-or-one-of-two-others-but-no – jruizaranguren Oct 03 '16 at 06:49
  • @jruizaranguren You are right that not-required doesn't mean forbidden, but you are wrong that this schema is incorrect. But don't take my word for it; try it. – Jason Desrosiers Oct 03 '16 at 17:01
  • @GetOffMyLawn This isn't the first time I've heard of Visual Studio having a bug in validating JSON Schemas. I don't recall if it was this same issue or not. It's possible that you will need to resort to a less elegant solution to work around the bug. – Jason Desrosiers Oct 03 '16 at 17:04