简体   繁体   中英

How to create JSON schema for validate if given field of type string contains value from given string array

I need to create JSON Schema (can use any version) to validate the string field that may only contain values from given string array in other field.

MVE Example:

For the "picked" the only valid values are ones specified in "values"

Valid:

{
   "values": ["Foo", "Bar", "Baz"],
   "picked": "Bar"
}

Invalid:

{
   "values": ["Foo", "Bar", "Baz"],
   "picked": "NotFromValues"
}

Schema:

{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
        "values": {
            "type": "array",
            "items": { "type": "string" }
        },
        "picked": {
            "type": "string"
// How can I validate picked?
        }
    }
}

What you're wanting isn't supported by json schema out of the box. You'll need some custom logic to do it.

There has been a lot of discussion on the spec repo about it. If you do a search for issues with the $data label, you'll have a lot to read. The short of it is that no one could agree on how it should work. The topic is now all but abandoned.

To address this, I have taken advantage of the 2019-09 (and later) vocabularies feature. I have written a new vocabulary that defines a data keyword to support this kind of behavior. The catch is it's only supported (to my knowledge) in my implementation, JsonSchema.Net, but you could implement it yourself if you're using an implementation that lets you define your own keywords.

For your example, you'll need this:

{
    "$schema": "https://gregsdennis.github.io/json-everything/meta/data",
    "type": "object",
    "properties": {
        "values": {
            "type": "array",
            "items": { "type": "string" }
        },
        "picked": {
            "type": "string",
            "data": {
                "enum": "#/values"
            }
        }
    }
}

(Note that the $schema value changed.)

This will find the values property at the root of your instance (an array), replace "/values" with that, then evaluate as if the value of data was a schema.

In the end, for your example, you're evaluating against this schema:

{
    "$schema": "https://gregsdennis.github.io/json-everything/meta/data",
    "type": "object",
    "properties": {
        "values": {
            "type": "array",
            "items": { "type": "string" }
        },
        "picked": {
            "type": "string",
            "enum": [ "Foo", "Bar", "Baz" ]
        }
    }
}

but the value of enum comes from the instance.

You can test this at https://json-everything.net/json-schema .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM