1

Reposting the question How to implement conditional nested properties with JSON Schema (marked as duplicate though its a completely different problem) My JSON schema reads below tried based on : JSON Schema if/then require nested object

{
  "$id": "myschema.json",
  "if":{
    "type":"object",
    "properties": {
      "common_data": {
        "type":"object",
        "properties":{
          "remote_os": {
              "type":"object",
              "required":["common_data"],
              "const": "Linux"
            }
          },
          "required":["remote_os"]
      }
    }
  },
  "then": {
    "type":"object",
    "properties": {
      "file": {
        "type": "string",
        "pattern": "^(.*.)(bin)$"
        }
      }
  },
  "else": {
    "type":"object",
    "properties": {
      "file": {
        "type": "string",
        "pattern": "^(.*.)(exe)$"
        }
      }
  }
}

Basically adding the if-else logic to make sure for remote_os=Linux file should end up with .bin and remote_os=Windows file should end up with .exe Now I am trying to validate against below data

{
  "common_data": {
    "remote_os": "Linux"
  },
  "file": "abc.bin"
}

Getting error : [<ValidationError: "'abc.bin' does not match '^(.*.)(exe)$'">]

When tried to debug what properties python jsonschema is trying build on top of this schema to validate my data. Got this

properties {'common_data': {'type': 'object', 'properties': {'remote_os': {'type': 'object', 'required': ['common_data'], 'const': 'Linux'}}, 'required': ['remote_os']}}
properties {'remote_os': {'type': 'object', 'required': ['common_data'], 'const': 'Linux'}}
properties {'file': {'type': 'string', 'pattern': '^(.*.)(exe)$'}}

So its always matching against the 'pattern': '^(.*.)(exe)$' irrespective of remote_os. Looking for some guidance, how to address this issue.

curiousguy
  • 3,212
  • 8
  • 39
  • 71
  • 1
    I marked it duplicate because that aspect was the most glaring problem, however now you've corrected that, I can see some other issues, and I'm happy to provide you with a solution! – Relequestual May 07 '21 at 08:56
  • @Relequestual thanks a lot. Yes I have spend sometime and tried to correct that going through few articles and similar problem. But still not able to make it work. You help here is greatly appreciated . – curiousguy May 07 '21 at 09:08

1 Answers1

1

You're close, but there are a few problems.

First, let's assess if our assumption is right... It looks like if is failing, and triggering the else schema value to be applied rather than the then schema value. We can check this by changing if to simply true.

Yup, the then subschema works OK when applied.

OK, so let's remove parts of the nested schema till it works as we expect...

Ah... Look. remote_os in our data is a string, but it has been defined in the schema as being an object. Remove type: object.

Those required keywords don't match the data location... they just need to be moved UP to the correct level...

We end up with this schema: (live demo: https://jsonschema.dev/s/CEwMw)

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "$id": "myschema.json",
  "if": {
    "type": "object",
    "required": [
      "common_data"
    ],
    "properties": {
      "common_data": {
        "type": "object",
        "required": [
          "remote_os"
        ],
        "properties": {
          "remote_os": {
            "const": "Linux"
          }
        }
      }
    }
  },
  "then": {
    "type": "object",
    "properties": {
      "file": {
        "type": "string",
        "pattern": "^(.*.)(bin)$"
      }
    }
  },
  "else": {
    "type": "object",
    "properties": {
      "file": {
        "type": "string",
        "pattern": "^(.*.)(exe)$"
      }
    }
  }
}

Further, another schema debugging tip, is take the if schema value out, and use that as your whole schema. That way you can find out why THAT is failing validation, rather than just guessing.

These are easy mistakes to make! I made a few while trying to fix it. The important thing is to know how to debug your schema. Test assumptions, and recognise subschemas.

Relequestual
  • 11,631
  • 6
  • 47
  • 83
  • Relequestual, the way you explained really appreciate. I have learnt from you the way we need to debug the schema . Thanks for that. – curiousguy May 07 '21 at 12:28
  • More than welcome! Should you find a question that doesn't fit on StackOverflow, feel free to join the JSON Schema slack server. We monitor the tag from here too =] – Relequestual May 07 '21 at 12:30
  • Actually I was trying to implement same for my actual JSON schema where I used `local JSON schema definition file` through `$ref` . My `$ref` file looks like : https://jsonschema.dev/s/RG9d8 and same schema (you tip) I populated here https://jsonschema.dev/s/8d2KN. While later working fine but the adding schema through `$ref` is again giving problem. Missing anything in my debugging – curiousguy May 07 '21 at 12:35
  • 1
    I would suggest you post another question with enough information to replicate the problem. You can test multi-document schemas using https://json-schema.hyperjump.io. How `$ref` works is often something people have to learn. It has nothing to do with files on a file system. – Relequestual May 07 '21 at 12:39