0

One of the fields in my data is as follows:

{
  "license":
    "url": "<some url>",
    "label": "<some label>"
}

I would like to validate that, for example, if the user provides either of the values for "url":

["http://creativecommons.org/licenses/by/4.0/",
 "https://creativecommons.org/licenses/by/4.0/"]

That the value of label must be one of:

["CC-BY", "CC BY 4.0", "CC-BY 4.0"]

And there are multiple different label options, supporting HTTP or HTTPS. I tried the following, but the validation failed (couldn't validate), and I couldn't find anything about corresponding values, just if one field exists, then another must exist (dependencies).

"license": {
    "type": "object",
    "properties": {
        "oneOf": [
            {
                "url": { "enum": ["http://creativecommons.org/licenses/by/4.0/", "https://creativecommons.org/licenses/by/4.0/"] },
                "label": { "enum": ["CC-BY", "CC BY 4.0", "CC-BY 4.0"] }
            },
            {
                "url": { "enum": ["http://creativecommons.org/publicdomain/zero/1.0/", "https://creativecommons.org/publicdomain/zero/1.0/"] },
                "label": { "enum": ["CC-0", "CC0", "CC0 1.0 Universal", "CC0 1.0"] }    
            },
            {
                "url": { "enum": ["http://creativecommons.org/licenses/by/3.0/", "https://creativecommons.org/licenses/by/3.0/"] },
                "label": { "enum": ["CC-BY", "CC-BY 3.0"] } 
            } 
... <and so on>

I tried a couple of different iterations of dependencies/properties in oneOf and nothing seemed to work.

R Jackson
  • 105
  • 3
  • 13

1 Answers1

0

I found the method that works - "oneOf" should be level with "properties" and encase the "properties" objects within it, as below.

"license": {
        "type": "object",
        "properties": {
            "url": { "type": "string", "format": "uri" },
            "label": { "type": "string" },
            "logo": { "type": "string", "format": "uri" }
        },
        "required": ["url", "label"],
        "oneOf": [
            {
                "properties": {
                    "url": { "enum": ["http://creativecommons.org/licenses/by/4.0/", "https://creativecommons.org/licenses/by/4.0/"] },
                    "label": { "enum": ["CC-BY", "CC BY 4.0", "CC-BY 4.0"] }
                }
            },
            {
                "properties": {
                    "url": { "enum": ["http://creativecommons.org/publicdomain/zero/1.0/", "https://creativecommons.org/publicdomain/zero/1.0/"] },
                    "label": { "enum": ["CC-0", "CC0", "CC0 1.0 Universal", "CC0 1.0"] }
                }   
            },
            {
                "properties": {
                    "url": { "enum": ["http://creativecommons.org/licenses/by/3.0/", "https://creativecommons.org/licenses/by/3.0/"] },
                    "label": { "enum": ["CC-BY", "CC-BY 3.0"] } 
                }
            },
... <and so on>
R Jackson
  • 105
  • 3
  • 13
  • 1
    You should also look at `if` `then` `else` and `const` if you're using draft-7 or newer. – Relequestual Aug 20 '18 at 08:44
  • Thanks @Relequestual! What would the syntax for that look like? I tried some `if`/`then` statements but it didn't validate. – R Jackson Aug 20 '18 at 14:30
  • Here's an example: https://stackoverflow.com/a/51539952/89211 - Looking again at your situation, `oneOf` is probably preferable to nested if / then / else statements! If you prefer, you can make each schema in your `oneOf` use `if` and `then` if you feel it makes things easier to read. (I don't think you need to use `const` here either). – Relequestual Aug 20 '18 at 14:59
  • If you'd like to discuss further, feel free to join the JSON Schema slack. Link via the website. – Relequestual Aug 20 '18 at 14:59