JSON schema equivalent of XML schema keyref - json

I am trying to create a JSON schema for data that looks like this:
{
"equipments": {
"A": {},
"B": {}
},
"work": [
{
"equipment": "A"
}
]
}
The schema I currently have is this:
{
"$id": "example",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"equipments":{
"type": "object",
"additionalProperties": true
},
"work": {
"type": "array",
"items": {
"type": "object",
"properties": {
"equipment": {
"type": "string",
}
}
}
}
}
}
In the equipments object different pieces of equipment are configured. These should then be referenced from items in the work array. In an XML schema I would do this with a keyref but I cannot find any equivalent for JSON schemas. Is there an equivalent or is this just not possible with JSON schemas?

It's not currently possible to validate relational data in JSON Schema.
There is a JSON Schema Vocabulary created to reference instance data, but I don't think that would do what you're looking for either.
There was an effort to define a Vocabulary for databases, but that has stalled.

Related

Can json schema references have a template?

I'm working on reducing json schema, to try and make it easier to follow. Many of my nodes are of the same general form:
{
"[$PassedName]": {
"type": "object",
"properties": {
"current": {
"type": "object",
"[$PassedName]" : {"$ref": "#/definitions/Objects/[$PassedName]"}
},
"history": {
"type": "array",
"[$PassedName]" : {"$ref": "#/definitions/Objects/[$PassedName]"}
}
}
}
}
What I'd like to do is to pass a string to a reference, so the reference could use that string in the given locations. For example, giving the reference the string value "SSN" would have a resultant schema of the following:
{
"SSN": {
"type": "object",
"properties": {
"current": {
"type": "object",
"SSN": "#/definitions/Objects/SSN"
},
"history": {
"type": "array",
"SSN": "#/definitions/Objects/SSN"
}
}
}
}
Is this at all possible with json schemas? I've more than a dozen of basically the same node, so I'd like to simplify, if possible.

UUIDs as object keys in JSON Schema

I am trying to define a JSON Schema for a JSON API that uses UUIDs as their key for a JSON object. What makes it more complex is that it is also a nested object.
Example:
{
"nodes": {
"7059e5ad-fac0-4fda-aa3e-2655d6e60506": {
"type": "Class",
"name": "Supermarket",
"data": {},
"instances": {},
}
}
}
Which has a generated schema like this:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"nodes": {
"type": "object",
"properties": {
"7059e5ad-fac0-4fda-aa3e-2655d6e60506": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"name": {
"type": "string"
},
"data": {
"type": "object"
},
"instances": {
"type": "object"
}
}
}
}
}
}
}
Is there a way I can make a schema where there are no UUIDs values in the schema because these values can be anything?
You can leverage the existing uuid format definition, in draft2019-09 and later:
"propertyNames": {
"format": "uuid"
},
"additionalProperties": {
.. definition of the values that go under the uuid properties ..
}
Replace properties with patternProperties, and your UUID with the following regular expression.
^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$
The patternProperties keyword is like the properties keyword, but you can use a regular expression for the key. This works in draft-04 JSON Schema, but it's highly recommended to use a newer version of JSON Schema if you can.
This regex was borrowed, but I'm reasonably confident it is for a UUID.

JSON Schema: Additional properties false for embedded objects

I have a json schema with hundreds of objects, each containing other objects and so on...
I want all my json schema objects to have the option "additionalProperties" set to false, but it seems that I have to set it for each object in the json schema.
Is there any solution like setting "additionalProperties" to false only once for all objects including multiple level of embedded objects in the whole schema ?
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Modified JSON Schema draft v4 that includes the optional '$ref' and 'format'",
"type": "object",
"properties": {
"id": {
"type": "string"
},
"box": {
"type": "object",
"properties": {
"anotherBox": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
}
},
"title": {
"type": "string"
}
}
}
Thank you

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.

JSON schema - possible to reference multiple schemas from one object?

Below is an extract from my JSON schema.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"images": {
"type": "array",
"items": { "$ref": "#/definitions/bits" },
}
},
"definitions": {
"identifier": {
"type": "string"
},
"bits": {
"type": "integer",
"enum": [
8,
16,
32
]
}
}
}
As specified, I believe an array of images, where each element consists of a string identifier and an integer whose value can be 8, 16 or 32, would be considered valid JSON data.
This is fine for some of my JSON data.
But what if I want to further constrain the schema such that the integer value can only be 32? How would I do that while still allowing some JSON data to be valid against the original schema?
Is it possible, for example, to reference two schemas in one object, E.g. something like:
items": { "$ref": "#/definitions/bits" AND "$ref": "#/definitions/otherSchema"}
You can use allOf to validate against multiple schemas.
{
"items": {
"allOf": [
{ "$ref": "#/definitions/bits" },
{ "$ref": "#/definitions/otherSchema" }
]
}
}