0

Having following JSON schema:

{
  "type": "object",
  "properties": {
    "SomeForms": {
      "additionalProperties": false,
      "properties": {
        "Forms": {
          "type": "object",
          "additionalProperties": false,
          "patternProperties": {
            "^(TestTestForm1|TestForm2)$": {
              "type": "object",
              "properties": {
                "Options": {
                  "type": "object",
                  "additionalProperties": false,
                  "patternProperties": {
                    "^(ExampleDropdown|ExampleCheckboxes)$": {
                      "type": "object",
                      "properties": {
                        "DefaultValue": {
                          "type": "string"
}}}}}}}}}}}}}

And following test JSON:

{
  "SomeForms": {
    "Forms": {
      "TestTestForm1": {
        "Options": {
          "ExampleDropdown": {
            "DefaultValue": "Dropdown"
}}}}}}

How I can make the DefaultValue have different type, depending on the parent "^(TestTestForm1|TestForm2)$"?
Example:
- if the parent is TestTestForm1, I want DefaultValue to be number
- if the parent is TestTestForm1, I want DefaultValue to be string

I am using Json.NET library to generate schemas, so the C# example would be best, but having JSON schema example would also be a clue for me.

Thanks in advance.

I tried:

"Forms": {
    "allOf": [
    { 
            "if": { "patternProperties": { "const": "TestTestForm1" } }, 
            "then": { "patternProperties" : { "TestTestForm1": { "properties": { "Options": { "patternProperties": { "properties": { "DefaultValue": { "type": "number" } } } } } } } } }
],

But I does not work. Main thing I don't know, is how to make "if" check on the parent name, not the value (above I am using "const", which I guess is correct only for checking the "value" of property, not it's name).

Mateusz
  • 3
  • 2
  • Does this answer your question? [how to set the type of a schema object based on the value of another property?](https://stackoverflow.com/questions/53881623/how-to-set-the-type-of-a-schema-object-based-on-the-value-of-another-property) I'm not sure but it looks like a question I've had a few years back. Check out the answer I've got, it worked perfectly in my case. – Zohar Peled Jun 22 '23 at 09:18
  • Hi. So the main issue I have is that I want to do "if" on the name of property, not it's value. I am not sure, how the "if" condition should look like in that case. – Mateusz Jun 22 '23 at 09:25
  • I edited description and added question about "if" structure. – Mateusz Jun 22 '23 at 09:32
  • Sorry, but I'm not an expert on JsonSchema. In fact, I haven't used it in over two years. The user that answered my question is an expert on this subject, I'll bet he can help you. Unfortunately, Stackoverflow doesn't really give you the ability to ping a specific user.... Hopefully, you'll get your answer. – Zohar Peled Jun 22 '23 at 09:37
  • i think it was covered in this topic https://stackoverflow.com/questions/57141416/jsonschema-required-property-dependent-on-parent-property – Power Mouse Jun 22 '23 at 16:14
  • Already saw that one. Againg, it is checking the "property value", while I need to check the property name. Not sure how to do that. – Mateusz Jun 23 '23 at 11:46

1 Answers1

0

You can't "look up" the schema tree in JSON Schema. So you need to put the condition the level of the Forms object as you did. But this results in a quite verbose solution like this:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "description": "JSON schema generated with JSONBuddy https://www.json-buddy.com",
  "type": "object",
  "properties": {
    "SomeForms": {
      "additionalProperties": false,
      "properties": {
        "Forms": {
          "type": "object",
          "additionalProperties": false,
          "patternProperties": {
            "^(TestTestForm1|TestForm2)$": {
              "type": "object",
              "properties": {
                "foo": { },
                "bar": { }
              }
            }
          },
          "allOf": [
            {
              "if": {
                "properties": { "TestTestForm1": true }
              },
              "then": {
                "properties": {
                  "TestTestForm1": {
                    "type": "object",
                    "properties": {
                      "Options": {
                        "type": "object",
                        "patternProperties": {
                          "^(ExampleDropdown|ExampleCheckboxes)$": {
                            "type": "object",
                            "properties": {
                              "DefaultValue": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            },
            {
              "if": {
                "properties": { "TestForm2": true }
              },
              "then": {
                "properties": {
                  "TestForm2": {
                    "type": "object",
                    "properties": {
                      "Options": {
                        "type": "object",
                        "patternProperties": {
                          "^(ExampleDropdown|ExampleCheckboxes)$": {
                            "type": "object",
                            "properties": {
                              "DefaultValue": {
                                "type": "number"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }
  }
}

I added empty definitions for "foo" and "bar" keys at the place where you could add parts of the schema which are in common.

I can't think of any shorter version to solve this.

Clemens
  • 1,744
  • 11
  • 20