Is there a way to have a rule in one object that references properties from a different object?

Viewed 111

I could not find any examples of this so I'm assuming it's not possible, but want to confirm.

I have a main schema that references other schemas: https://www.jsonschemavalidator.net/s/4aLvXa4I

{
  "$defs": {
    "mainSchema": {
      "$id": "https://example.com/person.schema.json",
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "type": "object",
      "properties": {
        "objectOne": {
          "$ref": "#/$defs/objectOne"
        },
        "objectTwo": {
          "$ref": "#/$defs/objectTwo"
        }
      }
    },
    "objectOne": {
      "type": "object",
      "properties": {
        "checkThisValue": {
          "type": "string",
          "enum": [
            "one",
            "two",
            "three"
          ]
        }
      }
    },
    "objectTwo": {
      "type": "object",
      "properties": {
        "whenSettingThisValue": {
          "type": "string",
          "enum": [
            "A",
            "B",
            "C"
          ]
        }
      }
    }
  },
  "$ref": "#/$defs/mainSchema"
}

I want to define this rule:

IF objectOne.checkThisValue == one 
THEN objectTwo.whenSettingThisValue MUST == A
Same for two=>B and three=>C

Is this possible somehow? How do I reference objectOne properties inside of objectTwo?

Edit

I tried to create an if rule for objectTwo that references objectOne here, but my syntax is wrong because it's not working. whenSettingThisValue is set to C and it's saying valid when it should be invalid: https://www.jsonschemavalidator.net/s/NNjEIhWW

    "objectTwo": {
      "type": "object",
      "properties": {
        "whenSettingThisValue": {
          "type": "string",
          "enum": [
            "A",
            "B",
            "C"
          ]
        }
      },
      "if": {
        "properties": {
          "objectOne": {
            "checkThisValue": {
              "const": "one"
            }
          }
        }
      },
      "then": {
        "properties": {
          "objectTwo": {
            "whenSettingThisValue": {
              "const": "A"
            }
          }
        }
      }
    }
  },

I also tried using a oneOf rule in mainSchema where both the subschemas are used, but it is not working either (this example should be invalid): https://www.jsonschemavalidator.net/s/WkmMasDC

"mainSchema": {
  "$id": "https://example.com/person.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "additionalProperties": false,
  "type": "object",
  "properties": {
    "objectOne": {
      "$ref": "#/$defs/objectOne"
    },
    "objectTwo": {
      "$ref": "#/$defs/objectTwo"
    }
  },
  "oneOf": [
    {
      "type": "object",
      "properties": {
        "objectOne": {
          "checkThisValue": {
            "const": "one"
          }
        },
        "objectTwo": {
          "whenSettingThisValue": {
            "const": "A"
          }
        }
      }
    }
  ]
},

Solution

Per answer my OneOf rule was malformed. This correctly checks a value in one object is set in response to another. I thought because I was referencing them in another schema with $ref I would have to do something special, but I don't.

https://www.jsonschemavalidator.net/s/HcVhrShk

  "oneOf": [
    {
      "type": "object",
      "properties": {
        "objectOne": {
          "properties": {
            "checkThisValue": {
              "const": "one"
            }
          }
        },
        "objectTwo": {
          "properties": {
            "whenSettingThisValue": {
              "const": "A"
            }
          }
        }
      }
    },
    {
      "type": "object",
      "properties": {
        "objectOne": {
          "properties": {
            "checkThisValue": {
              "const": "two"
            }
          }
        },
        "objectTwo": {
          "properties": {
            "whenSettingThisValue": {
              "const": "B"
            }
          }
        }
      }
    }
  ]
},
1 Answers

Yes you can. There is an if/then/else construct which takes schemas as its arguments, so you can define a rule "if property A exists with value X, then property B must exist with value Y" etc.

There are some examples here: https://json-schema.org/understanding-json-schema/reference/conditionals.html#if-then-else

edit: in your re-edit, change the oneOf clause to this:

  "oneOf": [
    {
      "type": "object",
      "properties": {
        "objectOne": {
          "properties": {
            "checkThisValue": {
              "const": "one"
            }
          }
        }
      }
    },
    {
      "type": "object",
      "properties": {
        "objectTwo": {
          "properties": {
            "whenSettingThisValue": {
              "const": "A"
            }
          }
        }
      }
    }
  ]
Related