How can i write the json schema if json has multiple data set
Here is the schema you are looking for.
{
"type": "object",
"required": ["employees"],
"properties": {
"employees": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" }
},
"required": ["id", "name"]
}
}
}
}
You were really close. The items
keyword has two forms. The value of items
can be a schema or an array of schemas(1).
If items
is a schema, it means that every item in the array must conform to that schema. This is the form that is useful in this case.
If the value of items
is an array of schemas, it describes a tuple. For example, this schema ...
{
"type": "array",
"items": [
{ "type": "boolean" },
{ "type": "string" }
]
}
would validate this ...
[true, "foo"]
- http://json-schema.org/latest/json-schema-validation.html#anchor37
JSON Schema to validate multiple similar objects inside an array
Specify the "data" object as type array and indicate the required elements in each item.
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "string"
},
"ready": {
"type": "string"
}
},
"required": [
"id",
"name",
"ready"
]
}
}
},
"required": [
"data"
]
}
JSON schema definition with multiple sets of enums for array attribute
You need to invert the order of the oneOf and the items keywords, so that the same oneOf clause is used for all items:
...
"states": {
"type": "array",
"oneOf": [
{
"items": {
"enum": ["Washington","Oregon","California"],
"description": "United States"
}
},
{
"items": {
"enum": ["British Columbia","Alberta", "Ontario"],
"description": "Canada"
}
}
]
},
...
jsonschema multiple values for string property
If you want data to be one of a fixed set of exact values, you can use enum
:
{
"type": "string",
"enum": ["stop", "go"]
}
So, to fit this in your example, try:
{
"type": "object",
"properties": {
"$gte": {
"type": "string",
"oneOf": [
{"pattern": "<some-pattern>"},
{"enum": ["TOKEN", "ANOTHER_TOKEN"]}
]
}
}
}
How to define a JSON schema that requires at least one of many properties
To require at least one of a set of properties, use required
inside a series of anyOf
options:
{
"type": "object",
"anyOf": [
{"required": ["id"]},
{"required": ["email"]}
// any other properties, in a similar way
],
"properties": {
// Your actual property definitions here
}
{
If any of the properties you want is present ("id"
, "email"
), then it will pass the corresponding option in allOf
.
Writing a class for JSON data with multiple possible types for a field
Okay, so this I what I ended up with, but it feels super awkward...
Maybe someone can suggest improvements:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
...
public interface Payload { }
public class Foo : Payload
{
[JsonProperty("kind")]
public string Kind { get; set; } = "foo";
[JsonProperty("fizz")]
public int Fizz { get; set; };
}
public class Bar : Payload
{
[JsonProperty("kind")]
public string Kind { get; set; } = "bar";
[JsonProperty("buzz")]
public string Buzz { get; set; };
}
public class Message
{
[JsonProperty("payload")]
[JsonConverter(typeof(PayloadConverter))]
public Payload Payload { get; set; }
}
And then defining a custom JsonConverter for message:
public class PayloadConverter : JsonConverter
{
public override bool CanConvert(Type objectType) =>
typeof(Payload).IsAssignableFrom(objectType);
public override object ReadJson(
JsonReader reader,
Type objectType,
object existingValue,
JsonSerializer serializer)
{
JObject obj = JObject.Load(reader);
Payload item = obj["kind"].ToString() switch
{
"foo" => new Foo(),
"bar" => new Bar(),
_ => null
};
if (item == null) return null;
serializer.Populate(obj.CreateReader(), item);
return item;
}
public override void WriteJson(
JsonWriter writer,
object value,
JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
}
JSON Schema - array with multiple different object types
You have it slightly wrong. Currently your schema says... for the pipeline array, either, all of the items must be foo
or all of the items must be baz
.
You need to change your location of anyOf
and items
...
items
applies to every item in the array.anyOf
checks that any of the subschema values are valid against the instance location (in this case, each item in the array).
{
"$id": "https://example.com/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"pipeline": {
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"additionalProperties": false,
"properties": {
"foo": {
"type": "string"
},
"someOption": {
"type": "integer"
}
},
"required": [
"foo"
]
}, {
"type": "object",
"additionalProperties": false,
"properties": {
"baz": {
"type": "string"
},
"anotherOption": {
"type": "integer"
}
},
"required": [
"baz"
]
}
]
}
}
}
}
How do I make a JSON object with multiple arrays?
On the outermost level, a JSON object starts with a {
and end with a }
.
Sample data:
{
"cars": {
"Nissan": [
{"model":"Sentra", "doors":4},
{"model":"Maxima", "doors":4},
{"model":"Skyline", "doors":2}
],
"Ford": [
{"model":"Taurus", "doors":4},
{"model":"Escort", "doors":4}
]
}
}
If the JSON is assigned to a variable called data, then accessing it would be like the following:
data.cars['Nissan'][0].model // Sentra
data.cars['Nissan'][1].model // Maxima
data.cars['Nissan'][2].doors // 2
for (var make in data.cars) {
for (var i = 0; i < data.cars[make].length; i++) {
var model = data.cars[make][i].model;
var doors = data.cars[make][i].doors;
alert(make + ', ' + model + ', ' + doors);
}
}
Another approach (using an associative array for car models rather than an indexed array):
{
"cars": {
"Nissan": {
"Sentra": {"doors":4, "transmission":"automatic"},
"Maxima": {"doors":4, "transmission":"automatic"}
},
"Ford": {
"Taurus": {"doors":4, "transmission":"automatic"},
"Escort": {"doors":4, "transmission":"automatic"}
}
}
}
data.cars['Nissan']['Sentra'].doors // 4
data.cars['Nissan']['Maxima'].doors // 4
data.cars['Nissan']['Maxima'].transmission // automatic
for (var make in data.cars) {
for (var model in data.cars[make]) {
var doors = data.cars[make][model].doors;
alert(make + ', ' + model + ', ' + doors);
}
}
Edit:
Correction: A JSON object starts with {
and ends with }
, but it's also valid to have a JSON array (on the outermost level), that starts with [
and ends with ]
.
Also, significant syntax errors in the original JSON data have been corrected: All key names in a JSON object must be in double quotes, and all string values in a JSON object or a JSON array must be in double quotes as well.
See:
- JSON specification
- JSONLint - The JSON validator
JSON schema with multiple nested anyOf
Although nested anyOf
works just fine in JSON Schema, I don't think that's the best solution in this case. Flattening the anyOf
s and using some definitions
cleans up the schema tremendously making it easier to reason about.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["virtual"],
"properties": {
"virtual": {
"type": "array",
"items": {
"type": "object",
"required": ["type"],
"anyOf": [
{ "$ref": "#/definitions/pdm" },
{ "$ref": "#/definitions/topaz" },
{ "$ref": "#/definitions/io" }
]
}
}
},
"definitions": {
"pdm": {
"properties":{
"type": { "const": "bus" },
"entity": { "const": "pde" },
... type specific properties ...
}
},
"topaz": {
"properties": {
"type": { "const": "bus" },
"entity": { "const": "topaz" },
... type specific properties ...
}
},
"io": {
"properties": {
"type": { "const": "io" },
... type specific properties ...
}
}
}
}
If you use if
/then
/else
or the Implication Pattern rather than the Enum Pattern, you can get better error messaging, but with a more complex schema.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["virtual"],
"properties": {
"virtual": {
"type": "array",
"items": {
"type": "object",
"required": ["type"],
"allOf": [
{ "$ref": "#/definitions/pdm" },
{ "$ref": "#/definitions/topaz" },
{ "$ref": "#/definitions/io" }
]
}
}
},
"definitions": {
"pdm": {
"if": {
"properties":{
"type": { "const": "bus" },
"entity": { "const": "pde" }
},
"required": ["type", "entity"]
},
"then": {
"properties": {
... type specific constraints ...
}
}
},
... additional types ...
}
Related Topics
Ruby Instance Method & Conditional Local Variable Assignment with Same Name
Numeric Literals Prepended with '0'
Encrypt Data Bag from Inside of Ruby Without Relying on Knife
Why Use Gems for Serving Assets Instead of the Vendor File
Rails Form_For Never Invokes the Create Controller Action to Use Redirect_To
Tilt (Kramdown) Preventing Erb Processing When Rendering Markdown
Ruby, Value Bucketing, Beautify Code
How to Return a Group of Sequential Numbers That Might Exist in an Array
Managing Conflicting Versions of Ruby Gems
Delayedjob: "Job Failed to Load: Uninitialized Constant Syck::Syck"
With Nokogiri I am Getting Error "Initialize': Getaddrinfo: No Such Host Is Known. (Socketerror)"
When Passing a Ruby Array as an Argument, Why Does '<<' Append While '+=' Does Not
Ruby Devise, Sessionscontroller.Create, JSON - Getting Nameerror: Undefined 'Build_Resource'
Render Erb from Database into View Problem Please Help!