Home > OS >  Using anyOf and not to pick combinations of elements in an object and eliminate others
Using anyOf and not to pick combinations of elements in an object and eliminate others

Time:07-24

I have a composite object made up of 3 elements. I want to be able to allow certain combinations of the elements and to allow showing one of the 3 elements. This is dependent on some state. Here is the object created for simplicity showing the 3 elements:

      {
       "$schema": "http://json-schema.org/draft-04/schema#",
       "$id": "https://example.com/schemas/long-schema",
       "type": "object",
       "properties": {
          "propA": { "$ref": "#/$defs/objectA" },
          "propB": { "$ref": "#/$defs/objectB" },
          "propC": { "$ref": "#/$defs/objectC" }
      },
       "$defs": {
          "objectA": {
            "type": "object",
            "a": { "type": "string", "enum": ["A"] }
          },
          "objectB": {
            "type": "object",
            "b": { "type": "string", "enum": ["B"] }
          },
          "objectC": {
            "type": "object",
            "c": { "type": "string", "enum": ["C"] }
          }
        }
      }

I believe a combination of anyOf and not should be able to accomplish this but I am not very sure how to use them in the correct combination or the syntax required: The 'not' here is isolated so I'm sure that's not how to combine it

Here is some beginnings of what I am trying to achieve:

 //Display any combination of B and C but not A
   "anyOf" : [
      "not":{ "$ref": "#/$defs/objectA" },
      "$comment" : "Choose objects B, C or B & C, but not A"
   ]

 //Display any combination of A and B but not C
    "anyOf" : [
          "not":{ "$ref": "#/$defs/objectC" },
          "$comment" : "A and B but not C, allowing any combination of A and B"
       ]

CodePudding user response:

You're almost there. Since you have a number of conditions, all of which must be met, you can put those inside allOf. You also need to make the items inside anyOf and allOf into objects (schemas).

Since you already define what the properties must contain in the above section, you only need to add what properties can and cannot appear. "Property X should not be present" can be represented with a not and required.

// type, properties, $defs here...
"allOf": [
  {
    //Display any combination of B and C but not A
    "$comment" : "Choose objects B, C or B & C, but not A",
    "not": { "required": [ "propA" ] },
    "anyOf": [
      { "required": ["propB"] },
      { "required": ["propC"] }
    ]
  },
  {
    //Display any combination of A and B but not C
    "$comment" : "A and B but not C, allowing any combination of A and B"
    "anyOf": [
      { "required": ["propA"] },
      { "required": ["propB"] }
    ],
    "not": { "required": [ "propC" ] }
  }
]

You can read more about declaring conditional conditions here: https://json-schema.org/understanding-json-schema/reference/conditionals.html

  • Related