Json schema with keys as data - json

I have some hard time dealing with json schema.
Suppose this is initial simple json.
[
{
"Field1": 1,
"Description": "Default"
},
{
"Field1": 77,
"Description": "NonDefault"
}
]
And this is schema written which is valid
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "array",
"items": {
"type": "object",
"properties": {
"Field1": {
"type": "integer"
},
"Description": {
"type": "string"
}
}
}
}
I wanted to change Json, to use "Field1" as key.
"Field1" is integer value.
I do not know values and how many Field1 there will be in json.
This is final JSON
{
"1": {
"Description": "Default"
},
"77": {
"Description": "NonDefault"
}
}
But how to write json-schema for this JSON?

TimRoberts' answer is almost there. What you want is to describe the item in the patternProperties subschema, similar to how you have items in your example schema.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"patternProperties": {
"^[0-9]*$": {
"type": "object",
"properties": {
"Description": { "type": "string" }
}
}
}
}

You can use "propertyNames" with a "pattern" element to create a regular expression to qualify your key names, instead of enumerating them all. I, personally, prefer your first layout.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"patternProperties": {
"^[0-9]*$": { "type": "string" }
}
}

Related

How Do I Require that a Sub-Property Must Exist Using JSON Schema?

In JSON Schema, I can use require to ensure that a property exists on the same level of the hierarchy, but I'm having trouble validating for nested ones.
Suppose I have following JSON Schema:
{
"type": "object",
"properties": {
"my_type": {
"type": "string"
},
"t1_data": {
"type": "object",
"properties": {
"id": {
"type": "string"
}
}
},
"t2_data": {
"type": "object",
"properties": {
"id": {
"type": "string"
}
}
}
}
}
How would I specify the following validations?
if my_type == "type1", then t1_data.id must exist
if my_type == "type2", then t2_data.id must exist
if my_type is anything else, validation passes
I've tried using the require and anyOf constructs but I could only get them to work at the same level of the hierarchy.
Thanks,
A possible solution is to combine allOf and if-then. It is a little bit verbose but I am not aware of any shorter way. Here is the schema for the case "type1":
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
"description": "JSON schema generated with JSONBuddy https://www.json-buddy.com",
"type": "object",
"properties": {
"my_type": {
"type": "string"
},
"t1_data": {
"type": "object",
"properties": {
"id": {
"type": "string"
}
}
},
"t2_data": {
"type": "object",
"properties": {
"id": {
"type": "string"
}
}
}
},
"allOf": [
{
"if": {
"properties": {
"my_type": {
"const": "type1"
}
}
},
"then": {
"properties": {
"t1_data": {
"type": "object",
"properties": {
"id": {
"type": "string"
}
},
"required": [ "id" ]
}
}
}
}
]
}
"type2" would be quite the same as next schema in the allOf array.

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.

Is it possible to reference to JSON data itself within a schema definition?

Is it possible to define a JSON schema to check inner data integrity? So that mistakes like "ba" could be detected without further runtime checks.
Data JSON
{
"childNames": ["foo", "bar", "baz"],
"children": [
{
"name": "foo"
},
{
"name": "ba"
}
]
}
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://tbd.com/foo/bar",
"type": "object",
"properties": {
"childNames": {
"type": "array",
"items": { "type": "string" }
},
"children": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"enum": { "$ref": "???" }
}
}
}
}
}
}
If you're using .Net, then you can do this with JsonSchema.Net and JsonSchema.Net.Data.
You'll need to use a custom vocabulary which defines the data keyword.
Your schema will need to change to:
{
"$schema": "https://gregsdennis.github.io/json-everything/meta/data",
"$id": "https://tbd.com/foo/bar",
"type": "object",
"properties": {
"childNames": {
"type": "array",
"items": { "type": "string" }
},
"children": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"data": {
"enum": "#/childNames"
}
}
}
}
}
}
}
Note the data keyword where your ??? was and the different meta-schema in the $schema keyword.
You can try it on https://json-everything.net/json-schema.
Information on how this works is here.
If you're not using .Net, you may need to figure out how to support this vocabulary (or work with the maintainer of the library you're using to do so).
Disclaimer: I'm the creator & maintainer of JsonSchema.Net and the other json-everything libraries.

JSON Schema reference resolution

I have a JSON schema that contains "$ref" tags and I am trying to get a version of the JSON schema that have the "$ref" tags resolved. I am only looking to resolve "$ref" from definition (tags) within the JSON Schema string (ie. not external resolution needed).
Is there a library that performs the resolution of the JSON Schema? (I am currently using org.everit.json.schema library, which is great, but I can't find how to do what I need).
For example, my original schema is:
{
"$id": "https://example.com/arrays.schema.json",
"description": "A representation of a person, company, organization, or place",
"title": "complex-schema",
"type": "object",
"properties": {
"fruits": {
"type": "array",
"items": {
"type": "string"
}
},
"vegetables": {
"type": "array",
"items": { "$ref": "#/$defs/veggie" }
}
},
"$defs": {
"veggie": {
"type": "object",
"required": [ "veggieName", "veggieLike" ],
"properties": {
"veggieName": {
"type": "string",
"description": "The name of the vegetable."
},
"veggieLike": {
"type": "boolean",
"description": "Do I like this vegetable?"
}
}
}
}
}
Which would resolve to something like this (notice that the "#defs/veggie" resolves to its definition inserted inline in the schema):
{
"$id": "https://example.com/arrays.schema.json",
"description": "A representation of a person, company, organization, or place",
"title": "complex-schema",
"type": "object",
"properties": {
"fruits": {
"type": "array",
"items": {
"type": "string"
}
},
"vegetables": {
"type": "array",
"items": {
"type": "object",
"required": [ "veggieName", "veggieLike" ],
"properties": {
"veggieName": {
"type": "string",
"description": "The name of the vegetable."
},
"veggieLike": {
"type": "boolean",
"description": "Do I like this vegetable?"
}
}
}
}
}
}
This isn't possible in the general sense, because:
the $ref might be recursive (i.e. reference itself again)
the keywords in the $ref might duplicate some of the keywords in the containing schema, which would cause some logic to be overwritten.
Why do you need to alter the schema in this way? Generally, a JSON Schema implementation will resolve the $refs automatically while evaluating the schema against provided data.

Json Schema Dependencies with Object Definitions

When using json schema 7 is it possible to set a dependency on an object definition references rather individual fields?
For example I have a type string and properties object. Depending on the type the properties object fields will be different but I don't want to set dependancy of every possible field. That's rather tedious e.g.
{
"$id": "https://sibytes.datagovernor.com/dataset.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "dataset",
"type": "object",
"properties": {
"dataset_type": {
"type": "string",
"description": ""
},
"dataset_properties": {
<< BASICALLY HERE I WANT THE REFERENCE OBJECT DEFINITION TO BE DEPENDENT ON THE DATASET TYPE ABOVE>>
"$ref": "http://example.com/tableproperties.schema.json"
"$ref": "http://example.com/tableproperties.fileproperties.json"
...there will be others.
}
}
}
So turns out this can de done using sub-schema's and predicates
https://json-schema.org/understanding-json-schema/reference/conditionals.html
{
"$id": "https://sibytes.datagovernor.com/dataset.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "dataset",
"type": "object",
"properties": {
"dataset_type": {
"enum": ["Table","View"],
"description": "This is the type of physical object that the dataset describes."
}
},
"dataset_properties": {
"allOf": [
{
"if": {
"properties": {"dataset_type":{"const": "Table"}}
},
"then": {
"properties": {
"dataset_properties" : {
"$ref": "dataset.table.schema.json#/definitions/dataset_properties"
}
}
}
},
{
"if": {
"properties": {"dataset_type":{"const": "View"}}
},
"then": {
"properties": {
"dataset_properties" : {
"$ref": "dataset.view.schema.json#/definitions/dataset_properties"
}
}
}
}
]
},
"required": ["dataset_type","dataset_properties"]
}