JSON and JSON Schema for XML Developers

JSON and JSON-Schema
for XML Developers
Roger L. Costello
February 5, 2014
Approved for Public Release; Distribution
Unlimited. Case Number 14-3179
© 2014 The MITRE Corporation. All rights reserved.
|2|
Trends in XML and JSON usage
80%
XML
70%
60%
50%
40%
JSON
30%
20%
10%
0%
2006
2007
2008
2009
2010
2011
2012
2013
Based on directory of 11,000 web APIs listed at Programmable Web, December 2013
Wow! I better have
expertise in both
XML and JSON
© 2014 The MITRE Corporation. All rights reserved.
|3|
Specifications
The JSON specification is here:
– http://www.ecma-international.org/publications/files/ECMAST/ECMA-404.pdf
There are two specifications for JSON-Schema
– http://json-schema.org/latest/json-schema-core.html
– http://json-schema.org/latest/json-schema-validation.html
© 2014 The MITRE Corporation. All rights reserved.
|4|
Table of Contents
 Comparison of XML and JSON
 JSON
 JSON Schema
© 2014 The MITRE Corporation. All rights reserved.
|5|
Viewing this Tutorial
 This tutorial is best viewed in slide show mode
– Under the View menu select Slide Show
 Periodically you will see an icon at the bottom, right of the slide
indicating that it is time to do a lab exercise. I strongly
recommend that you stop and do the lab exercise to obtain the
maximum benefit from this tutorial.
© 2014 The MITRE Corporation. All rights reserved.
|6|
XML is a data format
XML is a way of structuring data … XML is a data format.
© 2014 The MITRE Corporation. All rights reserved.
|7|
JSON is a data format
JSON is a way of structuring data … JSON is a data format.
© 2014 The MITRE Corporation. All rights reserved.
|8|
Example of XML-formatted data
The below XML document contains data about a book: its title,
authors, date of publication, and publisher.
<Book>
<Title>Parsing Techniques</Title>
<Authors>
<Author>Dick Grune</Author>
<Author>Ceriel J.H. Jacobs</Author>
</Authors>
<Date>2007</Date>
<Publisher>Springer</Publisher>
</Book>
© 2014 The MITRE Corporation. All rights reserved.
|9|
Same data, JSON-formatted
{
"Book":
{
"Title": "Parsing Techniques",
"Authors": [ "Dick Grune", "Ceriel J.H. Jacobs" ],
"Date": "2007",
"Publisher": "Springer"
}
}
© 2014 The MITRE Corporation. All rights reserved.
| 10 |
XML and JSON, side-by-side
{
<Book>
<Title>Parsing Techniques</Title>
<Authors>
<Author>Dick Grune</Author>
<Author>Ceriel J.H. Jacobs</Author>
</Authors>
<Date>2007</Date>
<Publisher>Springer</Publisher>
</Book>
© 2014 The MITRE Corporation. All rights reserved.
"Book":
{
"Title": "Parsing Techniques",
"Authors": [ "Dick Grune", "Ceriel J.H. Jacobs" ],
"Date": "2007",
"Publisher": "Springer"
}
}
| 11 |
Creating lists in XML and JSON
{
<Book>
<Title>Parsing Techniques</Title>
<Authors>
<Author>Dick Grune</Author>
<Author>Ceriel J.H. Jacobs</Author>
</Authors>
<Date>2007</Date>
<Publisher>Springer</Publisher>
</Book>
© 2014 The MITRE Corporation. All rights reserved.
"Book":
{
"Title": "Parsing Techniques",
"Authors": [ "Dick Grune", "Ceriel J.H. Jacobs" ],
"Date": "2007",
"Publisher": "Springer"
}
}
| 12 |
XML is a meta-language
 XML is a language that you use to create other languages.
 For example, on the previous slides we saw how to use XML to
create a Book language, consisting of <Book>, <Title>,
<Author>, and so forth.
© 2014 The MITRE Corporation. All rights reserved.
| 13 |
JSON is a meta-language
 JSON is also a language that you use to create other languages.
 For example, on the previous slides we saw how to use JSON to
create a Book language, consisting of "Book", "Title", "Author",
and so forth.
© 2014 The MITRE Corporation. All rights reserved.
| 14 |
An XML document is a tree
Book
Title
Parsing
Techniques
© 2014 The MITRE Corporation. All rights reserved.
Authors
Author
Author
Dick Grune
Ceriel J.H.
Jacobs
Date
Publisher
2007
Springer
| 15 |
A JSON Object is a tree
Book
Title
Authors
Date
Publisher
Parsing
Techniques
[“Dick Grune”,
“Ceriel J.H.
Jacobs”]
2007
Springer
© 2014 The MITRE Corporation. All rights reserved.
| 16 |
Trees are well-studied
 The tree data structure has been well-studied by computer
scientists and mathematicians.
 There are many well-known algorithms for processing and
traversing trees.
 Both XML and JSON are able to leverage this.
© 2014 The MITRE Corporation. All rights reserved.
| 17 |
XML Schema for Book
<xs:element name="Book">
<xs:complexType>
<xs:sequence>
<xs:element name="Title" type="xs:string" />
<xs:element name="Authors">
<xs:complexType>
<xs:sequence>
<xs:element name="Author" type="xs:string" maxOccurs="5"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Date" type="xs:gYear" />
<xs:element name="Publisher" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Springer" />
<xs:enumeration value="MIT Press" />
<xs:enumeration value="Harvard Press" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
© 2014 The MITRE Corporation. All rights reserved.
| 18 |
Equivalent JSON Schema
{
"$schema": "http://json-schema.org/draft-04/schema
"type": "object",
"properties": {
"Book": {
"type": "object",
"properties": {
"Title": {"type": "string"},
"Authors": {"type": "array", "minItems": 1, "maxItems": 5, "items": { "type": "string" }},
"Date": {"type": "string", "pattern": "^[0-9]{4}$"},
"Publisher": {"type": "string", "enum": ["Springer", "MIT Press", "Harvard Press"]}
},
"required": ["Title", "Authors", "Date"],
"additionalProperties": false
}
},
"required": ["Book"],
"additionalProperties": false
}
© 2014 The MITRE Corporation. All rights reserved.
| 19 |
Title with string type
{
"$schema": "http://json-schema.org/draft-04/schema
"type": "object",
"properties": {
<xs:element name="Title" type="xs:string" />
"Book": {
"type": "object",
"properties": {
"Title": {"type": "string"},
"Authors": {"type": "array", "minItems": 1, "maxItems": 5, "items": { "type": "string" }},
"Date": {"type": "string", "pattern": "^[0-9]{4}$"},
"Publisher": {"type": "string", "enum": ["Springer", "MIT Press", "Harvard Press"]}
},
"required": ["Title", "Authors", "Date"],
"additionalProperties": false
}
},
"required": ["Book"],
"additionalProperties": false
}
© 2014 The MITRE Corporation. All rights reserved.
| 20 |
Authors list
{
"$schema": "http://json-schema.org/draft-04/schema
"type": "object",
<xs:element name="Authors">
<xs:complexType>
"properties": {
<xs:sequence>
"Book": {
<xs:element name="Author" type="xs:string" maxOccurs="5"/>
"type": "object",
</xs:sequence>
</xs:complexType>
"properties": {
</xs:element>
"Title": {"type": "string"},
"Authors": {"type": "array", "minItems": 1, "maxItems": 5, "items": { "type": "string" }},
"Date": {"type": "string", "pattern": "^[0-9]{4}$"},
"Publisher": {"type": "string", "enum": ["Springer", "MIT Press", "Harvard Press"]}
},
"required": ["Title", "Authors", "Date"],
"additionalProperties": false
}
},
"required": ["Book"],
"additionalProperties": false
}
© 2014 The MITRE Corporation. All rights reserved.
| 21 |
Date with year type
{
"$schema": "http://json-schema.org/draft-04/schema
"type": "object",
"properties": {
<xs:element name="Date" type="xs:gYear" />
"Book": {
"type": "object",
"properties": {
"Title": {"type": "string"},
"Authors": {"type": "array", "minItems": 1, "maxItems": 5, "items": { "type": "string" }},
"Date": {"type": "string", "pattern": "^[0-9]{4}$"},
"Publisher": {"type": "string", "enum": ["Springer", "MIT Press", "Harvard Press"]}
},
"required": ["Title", "Authors", "Date"],
"additionalProperties": false
}
},
"required": ["Book"],
"additionalProperties": false
}
© 2014 The MITRE Corporation. All rights reserved.
| 22 |
Publisher with enumeration
{
"$schema": "http://json-schema.org/draft-04/schema
"type": "object",
"properties": {
"Book": {
"type": "object",
"properties": {
"Title": {"type": "string"},
"Authors": {"type": "array", "minItems": 1, "maxItems": 5, "items": { "type": "string" }},
"Date": {"type": "string", "pattern": "^[0-9]{4}$"},
"Publisher": {"type": "string", "enum": ["Springer", "MIT Press", "Harvard Press"]}
},
"required": ["Title", "Authors", "Date"],
"additionalProperties": false
<xs:element name="Publisher" minOccurs="0">
}
<xs:simpleType>
},
<xs:restriction base="xs:string">
"required": ["Book"],
<xs:enumeration value="Springer" />
"additionalProperties": false
<xs:enumeration value="MIT Press" />
}
© 2014 The MITRE Corporation. All rights reserved.
<xs:enumeration value="Harvard Press" />
</xs:restriction>
</xs:simpleType>
</xs:element>
| 23 |
Bootstrap the schema language
 An XML Schema is written in XML.
 A JSON Schema is written in JSON.
© 2014 The MITRE Corporation. All rights reserved.
| 24 |
Validate XML docs against XML Schema
XML
Schema
XML
(instance)
© 2014 The MITRE Corporation. All rights reserved.
XML
Schema
Validator
XML instance is valid/invalid
| 25 |
Validate JSON docs against JSON Schema
JSON
Schema
JSON
(instance)
© 2014 The MITRE Corporation. All rights reserved.
JSON
Schema
Validator
JSON instance is valid/invalid
| 26 |
JSON Schema validators
http://json-schema.org/implementations.html
© 2014 The MITRE Corporation. All rights reserved.
| 27 |
Online JSON Schema validator
http://json-schema-validator.herokuapp.com/index.jsp
Paste your JSON Schema in here
Paste your JSON in here 2
Click on the validate button 3
© 2014 The MITRE Corporation. All rights reserved.
1
Results of validation is
shown here 4
| 28 |
Command-line JSON Schema validator
Want to validate a JSON instance against a JSON Schema from
the command line? Download:
json-schema-validator-2.2.5-lib.jar
from:
https://bintray.com/fge/maven/json-schema-validator/view
and then, from a command line, type:
java -jar json-schema-validator-2.2.5-lib.jar schema.json instance.json
© 2014 The MITRE Corporation. All rights reserved.
| 29 |
Use a JSON Schema validator from a Java
program
Want to validate a JSON instance against a JSON Schema from a
Java program? Download:
json-schema-validator-2.2.5-lib.jar
from:
https://bintray.com/fge/maven/json-schema-validator/view
and then read the documentation on the Java API.
© 2014 The MITRE Corporation. All rights reserved.
| 30 |
Schema-for-Schemas
At the following URL is a JSON Schema. It is a schema for
validating JSON Schemas … it is a schema for schemas!
http://json-schema.org/draft-04/schema#
JSON
Schema for
Schemas
JSON
Schema
© 2014 The MITRE Corporation. All rights reserved.
JSON
Schema
Validator
JSON Schema is valid/invalid
| 31 |
Status of JSON Schema specifications
 JSON Schema is being developed under the auspicies of the




IETF standards organization.
The JSON Schema specification is currently at draft #4.
Work is proceeding on draft #5.
Draft #5 will contain a few new things, but will be mostly the
same as draft #4 (draft #5 is backward compatible with draft #4).
Here are the draft #5 changes:
https://groups.google.com/forum/#!topic/jsonschema/FSJmct8crXk
© 2014 The MITRE Corporation. All rights reserved.
| 32 |
JSON Schema mailing list
The Google Group where JSON Schema is discussed:
https://groups.google.com/forum/#!forum/json-schema
© 2014 The MITRE Corporation. All rights reserved.
| 33 |
JSON used to store location of tweets
(Eric Fisher)
https://www.mapbox.com/blog/twitter-map-every-tweet/
© 2014 The MITRE Corporation. All rights reserved.
| 34 |
JSON used to store location of tweets (cont.)
 Tracking geotagged tweets from Twitter’s public API for the last




three and a half years.
There are about 10 million public geotagged tweets every day,
which is about 120 per second.
The accumulated history adds up to nearly three terabytes of
compressed JSON and is growing by four gigabytes a day.
The map on the previous slide shows what 6,341,973,478 tweets
look like on a map.
Using this program to parse the JSON and pull out just each
tweet’s username, date, time, location, client, and text:
https://github.com/ericfischer/twitter-json
© 2014 The MITRE Corporation. All rights reserved.
| 35 |
OASIS using JSON
The OASIS Open Data Protocol (Odata) Technical Committee
(https://www.oasis-open.org/committees/odata) is currently
defining a JSON format for OData service metadata, and plan to
use JSON Schema as the basis for this format.
© 2014 The MITRE Corporation. All rights reserved.
| 36 |
Processing JSON and JSON Schema with
Java
 Gson is a Java library that can be used to convert Java Objects into
their JSON representation. It can also be used to convert a JSON
string to an equivalent Java object.
https://code.google.com/p/google-gson/
http://www.studytrails.com/java/json/java-google-jsonintroduction.jsp
 Class JsonReader: Reads a JSON encoded value as a stream of
tokens. This stream includes both literal values (strings, numbers,
booleans, and nulls) as well as the begin and end delimiters of
objects and arrays. The tokens are traversed in depth-first order,
the same order that they appear in the JSON document. Within
JSON objects, name/value pairs are represented by a single token.
http://googlegson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/g
son/stream/JsonReader.html
© 2014 The MITRE Corporation. All rights reserved.
| 37 |
JSON Design Philosophy
 StackOverflow Question:
Is there an XSLT equivalent for JSON? Something to allow me to
do transformations on JSON like XSLT does to XML.
 Response: Not too sure there is need for this, and to me lack of
tools suggests lack of need. JSON is best processed as objects
(the way it's done in JS anyway), and you typically use language
of the objects itself to do transformations (Java for Java objects
created from JSON, same for Perl, Python, Perl, c#, PHP and so
on). Just with normal assignments (or set, get), looping and so
on. I mean, XSLT is just another language, and one reason it is
needed is that XML is not an object notation and thus objects of
programming languages are not exact fits (impedance between
hierarchic xml model and objects/structs). [StaxMan]
http://stackoverflow.com/questions/1618038/xslt-equivalent-for-json
© 2014 The MITRE Corporation. All rights reserved.
| 38 |
http://www.freeformatter.com/xml-to-json-converter.html
© 2014 The MITRE Corporation. All rights reserved.
| 39 |
Example of XML-to-JSON
The online freeformatter.com tool converts this XML:
<Book id="MCD">
<Title>Modern Compiler Design</Title>
<Author>Dick Grune</Author>
<Publisher>Springer</Publisher>
</Book>
to this JSON:
{
"@id": "MCD",
"Title": "Modern Compiler Design",
"Author": "Dick Grune",
"Publisher": "Springer"
}
I like that it encodes XML attributes by prefixing the attribute name
with the @ symbol.
© 2014 The MITRE Corporation. All rights reserved.
| 40 |
Auto-converting XML to JSON: a bad idea?
Should you devise a way to auto-convert XML to JSON? In the below message the person says:
Based on our real-world experience, it is best to create the JSON design from scratch.
Do not auto-generate it from XML.
Hi all,
To throw in a view from a long-time XML user:
IPTC - www.iptc.org - builds XML-based news exchange formats for 17 years
now and was also challenged to do the same in JSON. After a long discussion
we refrained from automatically converting an existing XML data model to
JSON:
- currently no shared/common way to deal with namespaces in JSON
- designs like inline elements don't exist in JSON
- the element/attribute model has no corresponding design in JSON
- and a basic requirement of JSON users is: no complex data model, please!
Therefore we created
- a simplified data model for the news exchange in JSON - www.newsinjson.org
- compared to the richer but also more complex XML format www.newsml-g2.org
- a highly corresponding JSON model to an initial XML model for the rights
expression language ODRL as this is a set of data which cannot be
simplified: http://www.w3.org/community/odrl/work/json/ vs
http://www.w3.org/community/odrl/work/2-0-xml-encoding-constraint-draft-changes/
Both approaches were welcome and are used - and we learned: an XML-to-JSON
tool only is of limited help.
http://lists.xml.org/archives/xml-dev/201412/msg00022.html
© 2014 The MITRE Corporation. All rights reserved.
| 41 |
The upcoming slides
The following slides are organized as follows:
– Description of the JSON data format
– How to create JSON Schemas
© 2014 The MITRE Corporation. All rights reserved.
| 42 |
The JSON data format
© 2014 The MITRE Corporation. All rights reserved.
| 43 |
JSON value
A JSON instance contains a single JSON value. A JSON value may
be either an object, array, number, string, true, false, or null:
Acknowledgement: This “railroad” graphic comes from the JSON specification, as do the railroad graphics on the next several slides.
© 2014 The MITRE Corporation. All rights reserved.
| 44 |
JSON object
A JSON object is zero or more string-colon-value pairs, separated
by comma and wrapped within curly braces:
Example of a JSON object:
{ "name": "John Doe",
"age": 30,
"married": true }
© 2014 The MITRE Corporation. All rights reserved.
| 45 |
Empty object
A JSON object may be empty.
This is a JSON object: { }
© 2014 The MITRE Corporation. All rights reserved.
| 46 |
JSON array
A JSON array is used to express a list of values. A JSON array
contains zero or more values, separated by comma and wrapped
within square brackets:
Example of a JSON array
{ "name": "John Doe",
"age": 30,
"married": true,
"siblings": ["John", "Mary", "Pat"] }
© 2014 The MITRE Corporation. All rights reserved.
| 47 |
Empty array vs. array with a null value
[]
Array with no items in it.
© 2014 The MITRE Corporation. All rights reserved.
[ null ]
Array with one item in it.
| 48 |
Array of objects
Each item in an array may be any of the seven JSON values.
{
"name": "John Doe",
"age": 30,
"married": true,
"siblings": [
{"name": "John", "age": 25},
true,
"Hello World"
]
}
© 2014 The MITRE Corporation. All rights reserved.
The array contains 3 items.
The first item is an object,
the second item is a boolean,
and the third item is a string.
Do Lab1
| 49 |
JSON number
A number is an integer or a decimal and it may have an exponent:
{
"name": "John Doe",
"age": 30,
"married": true,
"siblings": ["John", "Mary", "Pat"]
}
© 2014 The MITRE Corporation. All rights reserved.
Example of a JSON number
| 50 |
JSON string
A string is a sequence of Unicode characters wrapped within
quotes (").
{
"name": "John Doe",
"age": 30,
"married": true,
"siblings": ["John", "Mary", "Pat"]
}
© 2014 The MITRE Corporation. All rights reserved.
Example of a JSON string
| 51 |
JSON chars are a superset of XML chars
JSON
XML
Lesson Learned: be careful converting JSON to XML
as the result may be a non-well-formed XML document.
© 2014 The MITRE Corporation. All rights reserved.
| 52 |
These characters must be escaped
If any of the following characters occur within a string, they must
be escaped by preceding them with a backslash (\):
– quotation mark ("),
– backslash (\),
– the control characters U+0000 to U+001F
© 2014 The MITRE Corporation. All rights reserved.
| 53 |
Expressing characters in hex format
A character may be represented as a hexadecimal number, like so:
\u006A or \u006a for the 'j' character.
© 2014 The MITRE Corporation. All rights reserved.
| 54 |
No multiline strings
JSON does not allow multiline strings.
http://json.org/
http://stackoverflow.com/questions/2392766/multiline-strings-in-json
© 2014 The MITRE Corporation. All rights reserved.
| 55 |
Achieving interoperability in a world where
different OS's represent newline differently
Each operating system has its own convention for signifying the end of a line of text:
Unix: the newline is a character, with the value hex A (LF).
MS Windows: the newline is a combination of two characters, with the values hex D (CR) and hex A
(LF), in that order.
Mac OS: the newline is a character, with the value hex D (CR).
This operating-system-dependency of newlines can cause interoperability problems: the newlines
in a string created on a Unix box will not be understood by applications running on a Windows box.
Here is how the newline problem is resolved in XML and in JSON:
XML: all newlines are normalized by an XML parser to hex A (LF). So it doesn't matter whether you
create your XML document on a Unix box, a Windows box, or a Macintosh box, all newlines will be
represented as hex A (LF).
JSON: multi-line strings are not permitted! So the newline problem is avoided completely. You can,
however, embed within your JSON strings the \n (LF) or \r\n (CRLF) symbols, to instruct processing
applications: "Hey, I would like a newline here."
That is quite an interesting difference in approach between XML and JSON for dealing with the
newline problem!
© 2014 The MITRE Corporation. All rights reserved.
| 56 |
Other JSON values
The values true, false, and null are literal values; they are not
wrapped in quotes.
{
"name": "John Doe",
"age": 30,
"married": true,
"siblings": ["John", "Mary", "Pat"]
}
© 2014 The MITRE Corporation. All rights reserved.
Example of a JSON boolean
| 57 |
Good use-case for null
Some people do not have a middle name, we can use null to
indicate “no value”:
{
“first-name": "John",
“middle-name": null,
“last-name": “Doe"
}
© 2014 The MITRE Corporation. All rights reserved.
| 58 |
This is a legal JSON instance
42
© 2014 The MITRE Corporation. All rights reserved.
| 59 |
so is this
"Hello World"
© 2014 The MITRE Corporation. All rights reserved.
| 60 |
and so is this
true
© 2014 The MITRE Corporation. All rights reserved.
| 61 |
and this
[ true, null, 12, "ABC" ]
© 2014 The MITRE Corporation. All rights reserved.
| 62 |
Whitespace is irrelevant
{
"name": "John Doe",
"age": 30,
"married": true
}
equivalent
{"name":"John Doe","age":30,"married":true}
© 2014 The MITRE Corporation. All rights reserved.
| 63 |
String delimiters: JSON vs. XML
 JSON strings are always delimited by double quotes.
 XML strings (such as attribute values) may be delimited by
either double quotes or single quotes.
© 2014 The MITRE Corporation. All rights reserved.
| 64 |
JSON is recursively defined
{
"foo": json-value
}
The above JSON instance is an object. The
object has a single property, "foo". Its value is
any JSON value – recursive definition!
© 2014 The MITRE Corporation. All rights reserved.
| 65 |
Using JSON you can define arbitrarily
complex structures
{
"Book":
{
"Title": "Parsing Techniques",
"Authors": [ "Dick Grune", "Ceriel J.H. Jacobs" ]
}
}
{
"Book":
{
"Title": "Parsing Techniques",
"Authors": [
{"name":"Dick Grune", "university": "Vrije Universiteit"},
{"name":"Ceriel J.H. Jacobs", "university": "Vrije Universiteit"}
]
}
}
© 2014 The MITRE Corporation. All rights reserved.
| 66 |
Extend, ad infinitum
{
"Book":
{
"Title": "Parsing Techniques",
"Authors": [
{"name": {"first":"Dick", "last":"Grune"},
"university": "Vrije Universiteit"},
{"name": {"first":"Ceriel", "last":"Jacobs"},
"university": "Vrije Universiteit"}
]
}
}
© 2014 The MITRE Corporation. All rights reserved.
| 67 |
7 simple JSON components, assemble to
generate unlimited complexity
Integer
Null
Boolean
Object
Array
© 2014 The MITRE Corporation. All rights reserved.
String
Number
| 68 |
JSON provides the structures and assembly
rules, you customize them for your needs
object
array
[ json-value, json-value, json-value, … ]
{
"___": json-value,
"___": json-value,
"___": json-value,
…
}
© 2014 The MITRE Corporation. All rights reserved.
string
"___"
| 69 |
JSON provides the structures and assembly
rules, you customize them for your needs
structures
object
array
[ json-value, json-value, json-value, … ]
{
"___": json-value,
"___": json-value,
"___": json-value,
…
}
© 2014 The MITRE Corporation. All rights reserved.
string
"___"
| 70 |
JSON provides the structures and assembly
rules, you customize them for your needs
assembly points
object
array
[ json-value, json-value, json-value, … ]
{
"___": json-value,
"___": json-value,
"___": json-value,
…
}
© 2014 The MITRE Corporation. All rights reserved.
string
"___"
| 71 |
JSON provides the structures and assembly
rules, you customize them for your needs
object
array
[ json-value, json-value, json-value, … ]
{
"___": json-value,
"___": json-value,
"___": json-value,
…
string
"___"
}
customize
© 2014 The MITRE Corporation. All rights reserved.
| 72 |
oXygen XML supports JSON
You can create and edit JSON instances and JSON Schemas
using oXygen XML and it will check that the document is correctly
formatted. Nice!
© 2014 The MITRE Corporation. All rights reserved.
| 73 |
MS Visual Studio supports JSON Schema
 Visual Studio provides a wonderful editor that helps you create
JSON Schemas.
 The editor is available in the free Community version of Visual
Studio 2013.
 Here's a YouTube presentation on how to create JSON Schemas
using Visual Studio:
https://www.youtube.com/watch?v=Jt5SCNC87d4
Do Lab2
© 2014 The MITRE Corporation. All rights reserved.
| 74 |
FAQ
 Q: I don't see any JSON constructs that are equivalent to XML
attributes.
 A: Correct, there are no attributes in JSON.
 Q: Is there a namespace construct in JSON? If not, why was it
deemed unnecessary?
 A: No namespaces in JSON. JSON is a reaction against the
complexity of XML and namespaces is one of the biggest
culprits, in terms of complexity.
Continued 
© 2014 The MITRE Corporation. All rights reserved.
| 75 |
FAQ
 Q: Does JSON have tools to extract nodes from one or more
instances and recombine them into a new instance?
 A: There is no equivalent of XSLT in JSON. The JSON people
believe that text documents should be processed by a general
purpose language such as Java or JavaScript, not a domainspecific language such as XSLT.
 Q: It appears to be trivially easy to convert from JSON to XML. Is
that correct or are there complicating factors?
 A: JSON to XML should be straightforward. Going the other way
is challenging, due to XML attributes and namespaces.
Acknowledgement: Thanks to Rob Simmons for the excellent questions.
© 2014 The MITRE Corporation. All rights reserved.
| 76 |
Generating railroad diagrams
 I love the railroad diagrams which are used to represent the
JSON language. What tool is used to generate these diagrams?
 There is an Online Railroad Diagram Generator. It creates SVG
syntax diagrams, also known as railroad diagrams, from
context-free grammars specified in EBNF. You can copy the SVG
code or take screen shots.
 You have to type in the grammar and it'll make the diagram.
© 2014 The MITRE Corporation. All rights reserved.
| 77 |
Generating railroad diagrams
For example, to create the railroad diagram for a JSON object, you
would use the code:
object ::= '{' ((string ':' value ) ( ',' string ':' value )*)? '}'
http://stackoverflow.com/questions/796824/tool-for-generating-railroad-diagram-used-on-json-org
© 2014 The MITRE Corporation. All rights reserved.
| 78 |
JSONx (JSON  XML)
JSONx is an IBM standard format to represent JSON as XML
This document specifies a mapping
between JSON and XML, known as
JSONx. It is used by several IBM products.
http://tools.ietf.org/html/draft-rsalz-jsonx-00
"phoneNumbers": [
"212 555-1111",
"212 555-2222"
]
© 2014 The MITRE Corporation. All rights reserved.
<json:array name="phoneNumbers">
<json:string>212 555-1111</json:string>
<json:string>212 555-2222</json:string>
</json:array>
| 79 |
xml2json
XML Shell (xmlsh, http://www.xmlsh.org) provides a capability to
convert XML to JSON: http://www.xmlsh.org/CommandXml2json
© 2014 The MITRE Corporation. All rights reserved.
| 80 |
How to create JSON Schemas
© 2014 The MITRE Corporation. All rights reserved.
| 81 |
A contract for data exchanges
Both XML Schema and JSON Schema may be used as a contract
for data exchanges:
conforms to
data
© 2014 The MITRE Corporation. All rights reserved.
Contract
(schema)
| 82 |
Fundamental difference between
XML Schema and JSON Schema
 XML Schema: specifies closed content unless deliberate
measures are taken to make it open (e.g., sprinkle the <any>
element liberally throughout the schema).
 JSON Schema: specifies open content unless deliberate
measures are taken to make it closed (e.g., sprinkle
"additionalProperties": false liberally throughout the schema).
Definition of Open Content: instance
documents can contain items above and
beyond those specified by the schema.
Definition of Closed Content: instance
documents can contain only those items
specified by the schema.
© 2014 The MITRE Corporation. All rights reserved.
| 83 |
The power of JSON Schema comes from:
 Regular expressions (regexes): JSON Schema uses regexes a lot.
The regular expression language is well-established and very
powerful. Most data constraints can be expressed using regexes.
 Recursion: nearly all keywords in JSON Schema are recursively
defined, so you are limited only by your imagination in what you
create.
 Simplicity: JSON Schema doesn't have a large set of data types or
other features. It employs simple components which may be
assembled to generate arbitrary complexity.
© 2014 The MITRE Corporation. All rights reserved.
| 84 |
The power of JSON Schema comes from:
 Regular expressions (regexes): JSON Schema uses regexes a lot.
The regular expression language is well-established and very
powerful. Most data constraints can be expressed using regexes.
 Recursion: nearly all keywords in JSON Schema are recursively
defined, so you are limited only by your imagination in what you
create.
 Simplicity: JSON Schema doesn't have a large set of data types or
other features. It employs simple components which may be
assembled to generate arbitrary complexity.
Awesome
© 2014 The MITRE Corporation. All rights reserved.
| 85 |
A JSON Schema is a JSON object
{
"keyword": value,
"keyword": value,
"keyword": value,
…
}
© 2014 The MITRE Corporation. All rights reserved.
| 86 |
A JSON Schema is a JSON object
{
"keyword": value,
"keyword": value,
"keyword": value,
…
}
The JSON Schema specification defines
the set of keywords and values that can
be used to construct a schema. In this
tutorial we will learn the keywords that
may be used in a JSON Schema.
© 2014 The MITRE Corporation. All rights reserved.
| 87 |
Empty schema
{}
This is a valid JSON Schema!
It places no restrictions on
JSON instances.
© 2014 The MITRE Corporation. All rights reserved.
| 88 |
Every JSON instance is valid!
{}
JSON
JSON
Schema
Validator
Valid!
instance
Do Lab3
© 2014 The MITRE Corporation. All rights reserved.
| 89 |
"$schema" keyword
{
"$schema": "http://json-schema.org/draft-04/schema#",
…
}
© 2014 The MITRE Corporation. All rights reserved.
| 90 |
"$schema" keyword
{
"$schema": "http://json-schema.org/draft-04/schema#",
…
}
The $schema keyword says: This object is a
JSON schema, conforming to the schema
at http://json-schema.org/draft-04/schema#.
© 2014 The MITRE Corporation. All rights reserved.
| 91 |
"type" keyword
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "type",
…
}
© 2014 The MITRE Corporation. All rights reserved.
| 92 |
"type" keyword
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "type",
…
}
The type keyword says: The JSON instance
must be of this type. There are seven types:
-
"boolean"
-
"number"
-
"integer"
-
"string"
-
"array"
-
"object"
-
"null"
© 2014 The MITRE Corporation. All rights reserved.
| 93 |
Boolean type
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "boolean"
}
This schema constrains instances
to contain only a boolean value
(true or false).
© 2014 The MITRE Corporation. All rights reserved.
| 94 |
Only boolean instances are valid
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "boolean"
}
JSON
Schema
Validator
Valid!
© 2014 The MITRE Corporation. All rights reserved.
true
| 95 |
String instances are not valid
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "boolean"
}
JSON
Schema
Validator
Not valid!
© 2014 The MITRE Corporation. All rights reserved.
"Hello World"
| 96 |
Alert! "true" is not a Boolean value
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "boolean"
}
JSON
Schema
Validator
Not valid!
© 2014 The MITRE Corporation. All rights reserved.
"true"
| 97 |
Run example01
 Open the example01 folder (in the examples folder).
 In that folder are two files:




– schema.json
– instance.json
Open the files in oXygen XML.
Copy to the clipboard the content of schema.json and then
paste it into the Schema section of this online validator:
http://json-schema-validator.herokuapp.com/index.jsp
Copy to the clipboard the content of instance.json and then
paste it into the Data section.
Press the validate button.
© 2014 The MITRE Corporation. All rights reserved.
| 98 |
http://json-schema-validator.herokuapp.com/index.jsp
Paste schema here
1
Instance is valid!
4
Paste instance here 2
Press the Validate button 3
© 2014 The MITRE Corporation. All rights reserved.
| 99 |
Order of keywords is irrelevant
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "boolean"
}
equivalent!
{
"type": "boolean",
"$schema": "http://json-schema.org/draft-04/schema#"
}
© 2014 The MITRE Corporation. All rights reserved.
| 100 |
Number type
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "number"
}
This schema constrains instances
to contain only a number (integer,
decimal, number with exponent).
© 2014 The MITRE Corporation. All rights reserved.
| 101 |
Only numeric instances are valid
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "number"
}
JSON
Schema
Validator
Valid!
© 2014 The MITRE Corporation. All rights reserved.
12.3
| 102 |
Examples of numeric values
12
99.1 12.123e3 12.123E3
12.123 x 103
© 2014 The MITRE Corporation. All rights reserved.
| 103 |
"enum" keyword
 The value of enum is an array.
 The items in the array is a list of values that instances may have.
 The following schema says that the only allowable values in
instances are the numbers: 2, 4, 6, 8, 10.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "number",
"enum": [2, 4, 6, 8, 10]
}
See example02
© 2014 The MITRE Corporation. All rights reserved.
| 104 |
"minimum" and "maximum" keywords
 A range of values can be specified using the "minimum" and
"maximum" keywords.
 The following schema constrains instances to numbers in the
range 0-100, inclusive.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "number",
"minimum": 0,
"maximum": 100
}
© 2014 The MITRE Corporation. All rights reserved.
| 105 |
"exclusiveMinimum", "exclusiveMaximum"
 A range's endpoints can be made exclusive by using the
"exclusiveMinimum" and "exclusiveMaximum" keywords.
 The following schema constrains instances to numbers in the
range 0-100, exclusive.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "number",
"minimum": 0,
"maximum": 100,
"exclusiveMinimum": true,
"exclusiveMaximum": true
}
See example03
© 2014 The MITRE Corporation. All rights reserved.
| 106 |
"multipleOf" keyword
 Instances can be constrained to a number that is a multiple of a
number.
 The following schema says that a JSON instance must be a
number 0-100, inclusive, and must be a multiple of 2.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "number",
"minimum": 0,
"maximum": 100,
"multipleOf": 2
}
Here are four schema-valid values: 0
See example04
© 2014 The MITRE Corporation. All rights reserved.
2
4
100
| 107 |
"multipleOf" value
The value of "multipleOf" must be greater than 0 (no negative
numbers).
© 2014 The MITRE Corporation. All rights reserved.
| 108 |
Integer type
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "integer"
}
This schema constrains instances to contain only an
integer.
Here are two schema-valid values: -900
© 2014 The MITRE Corporation. All rights reserved.
129
| 109 |
Number constraints also apply to integer
The constraints that apply to "number" also apply to "integer":
– enum
– minimum
– maximum
– exclusiveMinimum
– exclusiveMaximum
– multipleOf
Do Lab4
© 2014 The MITRE Corporation. All rights reserved.
| 110 |
String type
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "string"
}
This schema constrains instances to contain only a
string.
© 2014 The MITRE Corporation. All rights reserved.
| 111 |
"maxLength" keyword
The maximum length of a string is constrained using the
"maxLength" keyword.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "string",
"maxLength": 20
}
Here is a schema-valid value: "Hello World"
See example05
© 2014 The MITRE Corporation. All rights reserved.
| 112 |
Value of "maxLength"
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "string",
"maxLength": ___
}
Must be an integer, ≥ 0
© 2014 The MITRE Corporation. All rights reserved.
| 113 |
"minLength" keyword
 The "minLength" keyword is used to specify the shortest string
length allowed.
 The value of "minLength" must be an integer, greater than or
equal to 0.
 The default value is 0.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "string",
"minLength": 5,
"maxLength": 20
}
© 2014 The MITRE Corporation. All rights reserved.
| 114 |
"pattern" keyword
 The set of characters that can be used in a string can be
constrained using the "pattern" keyword, whose value is a
regular expression [1].
 The following schema constrains the set of characters to the
lower- and upper-case letters of the English alphabet, plus the
space character.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "string",
"maxLength": 20,
"pattern": "^[a-zA-Z ]*$"
}
See example06
[1] What flavor of regexes does JSON Schema use? Answer: ECMA 262.
http://www.ecma-international.org/ecma-262/5.1/#sec-15.10
© 2014 The MITRE Corporation. All rights reserved.
| 115 |
"pattern" value is a regular expression
 The value of "pattern" is a regular expression.
 The regular expressions are not implicitly anchored (as they are
in XML Schema) so you must use the start and end anchors
(^…$).
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "string",
"maxLength": 20,
"pattern": "^[a-zA-Z ]*$"
}
This symbol indicates that a string must end
with the letters of the alphabet plus space.
This symbol indicates that a string must start
with the letters of the alphabet plus space.
© 2014 The MITRE Corporation. All rights reserved.
| 116 |
How to read this JSON Schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "string",
"maxLength": 20,
"pattern": "^[a-zA-Z ]*$"
}
“
The string in a JSON instance cannot have a length greater than
20 characters and the characters must be a-z, A-Z, or space.
”
© 2014 The MITRE Corporation. All rights reserved.
| 117 |
Components of regular expressions
Basic pattern
Matching string
x
The character x
.
Any character, except newline
Legend:
[xyz ...]
Any of the characters, x, y, z, …
x, y, z, … stand for any character
R, R1, R2, …stand for any regular
expression
Repetition operators:
R?
R is optional (zero or one
occurrence)
R*
Zero or more occurrences of R
R+
One or more occurrences of R
Operator Precedence:
Repetition operators have the
highest precedence (bind most
tightly); next comes the
concatenation operator; and the
alternatives operator | has the
lowest precedence
Compositional operators:
R1R2
An R1 followed by an R2
R1|R2
Either an R1 or an R2
Acknowledgement: This table comes
from Modern Compiler Design by
Grune et al, p62.
Grouping:
(R)
© 2014 The MITRE Corporation. All rights reserved.
R itself
| 118 |
Escaping the dot (.) and the dash (-)
 In regular expressions the dot (.) symbol means “any
character”
 Suppose that you want the dot (.) symbol, not “any character”.
How would you express that? You might think, do this: \.
 However, that’s not correct. You need to escape the backslash.
Here’s how to do it: \\.
 Similarly, in regular expressions the dash (-) symbol means
“range-of-characters”
 Suppose that you want the dash (-) symbol, not “range-ofcharacters”. Here’s how to express it: \\-
© 2014 The MITRE Corporation. All rights reserved.
| 119 |
Enumerate the allowed string
 The "enum" keyword can be used with the string type.
 The following schema says that only three strings are allowed:
"red", "white", or "blue".
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "string",
"enum": ["red", "white", "blue"]
}
Here’s a schema-valid instance: "red"
See example07
© 2014 The MITRE Corporation. All rights reserved.
| 120 |
"enum" applies to all types
The "enum" keyword can be used with all seven types.
© 2014 The MITRE Corporation. All rights reserved.
| 121 |
"enum" without "type"
 When the "type" keyword" is specified, then all the values in the
"enum" array must conform to that type.
 If the "type" keyword is omitted, then the values in the "enum"
array can be of any type.
 The following schema says that a JSON instance can be the
string: "red", the number 12, or the boolean false.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"enum": ["red", 12, false]
}
© 2014 The MITRE Corporation. All rights reserved.
| 122 |
"format" keyword
 The "format" keyword is used to specify the format of a string.
 The following schema says that JSON instances must consist of
a string and the string must be formatted as an ISO 8601
date/time value.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "string",
"format": "date-time"
}
Here’s a schema-valid instance: "2014-06-20T12:50:00Z"
See example08
© 2014 The MITRE Corporation. All rights reserved.
| 123 |
date-time format
A string with format date-time must conform to one of these two
forms:
yyyy-MM-dd'T'HH:mm:ssZ
yyyy-MM-dd'T'HH:mm:ss.SSSZ
© 2014 The MITRE Corporation. All rights reserved.
| 124 |
"format" keyword values
 Here are the valid values for the "format" keyword:
– "date-time"
– "email"
– "hostname"
– "ipv4"
– "uri"
 Those values are called format attributes.
 The "format" keyword may only be used with the string type.
© 2014 The MITRE Corporation. All rights reserved.
| 125 |
Examples of "format" values
 "date-time"




"2014-06-20T12:50:00Z"
"email"
"smith@example.org"
"hostname"
"www.google.com"
"ipv4"
"192.168.5.0"
"uri"
"http://www.google.com"
Do Lab5
© 2014 The MITRE Corporation. All rights reserved.
| 126 |
Array
© 2014 The MITRE Corporation. All rights reserved.
| 127 |
Array type
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array"
}
© 2014 The MITRE Corporation. All rights reserved.
| 128 |
Array type
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array"
}
This schema constrains instances
to contain only an array.
Here’s a schema-valid value:
["value1", "value2", 12, null]
© 2014 The MITRE Corporation. All rights reserved.
| 129 |
Enumerate the allowed arrays
 The "enum" keyword can be used with the array type.
 The following schema says that instances may be either of these
arrays: ["A", "B"] or [1,2,3].
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"enum": [["A", "B"], [1,2,3]]
}
Here are the only two valid instance values: ["A", "B"]
See example09
© 2014 The MITRE Corporation. All rights reserved.
[1,2,3]
| 130 |
"maxItems" keyword
 The maximum number of items in the array is specified using
the "maxItems" keyword.
 The following schema says that JSON instances must consist of
an array and the instance cannot contain more than three items.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"maxItems": 3
}
Here’s a schema-valid instance:
See example10
© 2014 The MITRE Corporation. All rights reserved.
[ 1, true, ["A", "B"] ]
| 131 |
The items can be anything
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"maxItems": 3
}
This constrains the number of array items to three.
But each of those items can be anything.
© 2014 The MITRE Corporation. All rights reserved.
| 132 |
"items" keyword
 The items in an array can be constrained using the "items"
keyword.
 The value of "items" is a JSON Schema.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"maxItems": 3,
"items": JSON Schema
}
© 2014 The MITRE Corporation. All rights reserved.
| 133 |
Recursive definition!
{
This JSON
Schema
contains this
JSON
Schema
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"maxItems": 3,
"items": JSON Schema
}
© 2014 The MITRE Corporation. All rights reserved.
| 134 |
All that we’ve learned applies to the
subschema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"maxItems": 3,
"items": {
"keyword": value,
"keyword": value,
"keyword": value,
…
}
}
The value of "items" can be all the things
that we've seen: the "type" keyword, the
"maxLength" keyword for strings, the
"minimum" and "maximum" keywords for
numbers, and so forth.
© 2014 The MITRE Corporation. All rights reserved.
| 135 |
Terminology: root schema, subschema
{
}
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"maxItems": 3,
"items": {{
"keyword":
"keyword":value,
value,
"keyword":
"keyword":value,
value,
"keyword":
"keyword":value,
value,
……
}}
root schema
© 2014 The MITRE Corporation. All rights reserved.
subschema
| 136 |
Don’t use $schema in subschemas
Yes
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"maxItems": 3,
"items": {
“$schema": "http://json-schema.org/draft-04/schema#",
"keyword": value,
"keyword": value,
…
}
No
}
"$schema" should only be used in the root schema, not in
subschemas. It’s not illegal in draft #4, but in draft v5,
$schema appearing in a subschema will be an error.
Do Lab6
© 2014 The MITRE Corporation. All rights reserved.
| 137 |
Default value for "items"
If "items" is not present, it has a default value of { }, which means
that each item in the array may be any value.
© 2014 The MITRE Corporation. All rights reserved.
| 138 |
Max of 3 items, each an integer
The following schema says that instances must not contain more
than 3 items and each item must be an integer.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"maxItems": 3,
"items": {
"type": "integer"
}
}
Here are four schema-valid instances: [1,2,3]
See example11
© 2014 The MITRE Corporation. All rights reserved.
[1,2]
[1]
[]
| 139 |
Max of 3 items, each an integer 0 – 100
The following schema says that instances must not contain more
than 3 items and each item must be an integer and the integer
must be between 0 and 100.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"maxItems": 3,
"items": {
"type": "integer",
"minimum": 0,
"maximum": 100
}
}
See example12
© 2014 The MITRE Corporation. All rights reserved.
| 140 |
"uniqueItems" keyword
We can require each item in the array be unique. This is
accomplished using the "uniqueItems" keyword.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"maxItems": 3,
"items": {
"type": "integer",
"minimum": 0,
"maximum": 100
},
"uniqueItems": true
}
The default value of "uniqueItems" is false.
See example13
© 2014 The MITRE Corporation. All rights reserved.
| 141 |
Max of 3 items, each a string with max length
20, consisting of letters and spaces only
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"maxItems": 3,
"items": {
"type": "string",
"maxLength": 20,
"pattern": "^[a-zA-Z ]*$"
}
}
See example14
© 2014 The MITRE Corporation. All rights reserved.
| 142 |
"items" with empty schema value
If the value of "items" is { } then each item may have any value.
The following schema permits each array item to be anything.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"maxItems": 3,
"items": {}
}
Here is a schema-valid instance: [ "hello world", 12, {"age":30} ]
See example15
© 2014 The MITRE Corporation. All rights reserved.
| 143 |
Equivalent!
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"maxItems": 3,
"items": {}
}
Equivalent since the default
value of "items" is { }
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"maxItems": 3
}
© 2014 The MITRE Corporation. All rights reserved.
| 144 |
Two legal values for "items"
 As we’ve seen, the value of "items" is an object (a JSON
Schema).
 Alternatively, the value of "items" may be an array. Each item in
the array must be an object (a JSON Schema).
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items": JSON Schema
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items": [
JSON Schema,
JSON Schema,
…
]
}
© 2014 The MITRE Corporation. All rights reserved.
This kind of array is
called an array tuple
| 145 |
Array may contain two strings
 The below schema specifies an array consisting of up to two
items.
 If the first item is present, it must be either the string "white" or
"black".
 If the second item is present, it must be either the string "cup"
or "plate".
 The array may be empty.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items": [
{ "type": "string", "enum": ["white", "black"] },
{ "type": "string", "enum": ["cup", "plate"] }
]
}
© 2014 The MITRE Corporation. All rights reserved.
| 146 |
Some legal instances
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items": [
{ "type": "string", "enum": ["white", "black"] },
{ "type": "string", "enum": ["cup", "plate"] }
]
}
Here are three valid values: [ "white", "cup"]
[ "white"]
[]
See example16
Do Lab7
© 2014 The MITRE Corporation. All rights reserved.
| 147 |
Array has open content!
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items": [
{ "type": "string", "enum": ["white", "black"] },
{ "type": "string", "enum": ["cup", "plate"] }
]
}
This schema specifies what the first two items in the array must
be, but it doesn’t say there can’t be additional items.
This is a valid value: [ "white", "cup", true, null, {"foo": 12} ]
additional items
© 2014 The MITRE Corporation. All rights reserved.
| 148 |
"additionalItems" keyword
 "additionalItems": false is used to specify that an array cannot
contain additional items.
 Now the array is constrained to no more than two items:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items": [
{ "type": "string", "enum": ["white", "black"] },
{ "type": "string", "enum": ["cup", "plate"] }
],
"additionalItems": false
}
See example17
Do Lab8
© 2014 The MITRE Corporation. All rights reserved.
| 149 |
Array tuple with { } for each value
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items": [
{},
{}
],
"additionalItems": false
}
The array must contain up to two items. Each item can be
anything: a number, integer, boolean, array, object, or null.
Here are 4 valid instances: [ ] [1]
See example18
© 2014 The MITRE Corporation. All rights reserved.
[1, true]
[1, [1, true]]
| 150 |
Desire: any number of additional items, but of
a certain type
 If we don’t specify "additionalItems": false, then instances can
have any number of additional items and each item can be
anything (of any type).
 We may want to allow any number of additional items, but they
are to be constrained to be of a certain type (e.g., constrain them
to be booleans)
© 2014 The MITRE Corporation. All rights reserved.
| 151 |
additionalItems with a JSON Schema value
 We have seen that additionalItems can have a boolean value.
 Alternatively, it can have a value that is an object (JSON
Schema)
"additionalItems": JSON Schema
© 2014 The MITRE Corporation. All rights reserved.
| 152 |
Any number of boolean values
 The below schema specifies that an instance must be an array
that contains one item: a string of max length 20, consisting of
the lower and uppercase letters plus space.
 Further, any number of boolean values may follow the string.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items": [
{ "type": "string", "maxLength": 20, "pattern": "^[a-zA-Z ]*$" }
],
"additionalItems": {"type": "boolean"}
}
Here are three valid instances: ["Hello World", true, false, false, true]
["Hello World"]
[]
See example19
© 2014 The MITRE Corporation. All rights reserved.
| 153 |
Restrict the additional items
 On the previous slide the schema allowed an unbounded
number of additional items (i.e., boolean values).
 We can restrict the total number of items (thus restricting the
number of additional items) using the "maxItems" keyword:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items": [
{ "type": "string", "maxLength": 20, "pattern": "^[a-zA-Z ]*$" }
],
"additionalItems": {"type": "boolean"},
"maxItems": 3
}
The total number of items that are allowed in the array is 3,
which means there can only be 2 boolean values.
See example19.1
© 2014 The MITRE Corporation. All rights reserved.
| 154 |
Valid and invalid instances
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items": [
{ "type": "string", "maxLength": 20, "pattern": "^[a-zA-Z ]*$" }
],
"additionalItems": {"type": "boolean"},
"maxItems": 3
}
These are schema-valid:
These are not schema-valid:
[]
[true]
["Hello World"]
["Hello World", true, false, false]
["Hello World", true]
["Hello World", true, false]
© 2014 The MITRE Corporation. All rights reserved.
| 155 |
Restrictions on "additionalItems": { … }
The value of "additionalItems" can be a schema only if "items" is
present and its value is an array tuple (an array of schemas).
© 2014 The MITRE Corporation. All rights reserved.
| 156 |
Default value of "additionalItems" is { }
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items": [
{ "type": "string", "enum": ["white", "black"] },
{ "type": "string", "enum": ["cup", "plate"] }
]
}
Equivalent
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "array",
"items": [
{ "type": "string", "enum": ["white", "black"] },
{ "type": "string", "enum": ["cup", "plate"] }
],
"additionalItems": { }
}
© 2014 The MITRE Corporation. All rights reserved.
The array may contain zero
or more additional items
and each additional item
may have any value.
| 157 |
Rules for constraining arrays
 If the value of "items" is a JSON Schema, then we can constrain
the number of items using "maxItems"
 If the value of "items" is an array, then we can prevent the
presence of additional items using "additionalItems": false
 If the value of "items" is an array and the value of "additionalItems"
is a JSON Schema, then we can constrain the total number of
items using "maxItems"
© 2014 The MITRE Corporation. All rights reserved.
| 158 |
How to constrain arrays:
If the schema has this:
then the array can be
constrained using this
keyword:
"type": "array"
"enum"
"type": "array",
"items": JSON Schema
"maxItems"
"type": "array",
"items": [ JSON Schema,
JSON Schema,
…
]
"additionalItems": false
"type": "array",
"items": [ JSON Schema,
JSON Schema,
…
],
"additionalItems": JSON Schema
"maxItems"
© 2014 The MITRE Corporation. All rights reserved.
| 159 |
The value of additionalItems is a choice
"type": "boolean"
"additionalItems":
JSON Schema
© 2014 The MITRE Corporation. All rights reserved.
| 160 |
Here is how the schema-for-schema defines
"additionalItems"
"additionalItems": {
"anyOf": [
{ "type": "boolean" },
{ "$ref": "#" }
],
"default": {}
},
© 2014 The MITRE Corporation. All rights reserved.
| 161 |
Object
© 2014 The MITRE Corporation. All rights reserved.
| 162 |
Object type
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object"
}
© 2014 The MITRE Corporation. All rights reserved.
| 163 |
Object type
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object"
}
The schema constrains instances to contain only an object.
Here’s a schema-valid value:
{
"X": 12,
"Y": "hello"
}
See example20
© 2014 The MITRE Corporation. All rights reserved.
| 164 |
Unconstrained object
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object"
}
The schema specifies no constraints on the object's properties
(i.e., name/value pairs).
© 2014 The MITRE Corporation. All rights reserved.
| 165 |
Enumerate the allowed objects
 The "enum" keyword can be used to enumerate the objects that
are allowed in instances.
 The following schema enumerates two objects:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"enum": [
{"name": "John Doe", "age": 30},
{"company": "Google", "product": "searching"}
]
}
Here are the only valid instances:
{"name": "John Doe", "age": 30}
See example21
© 2014 The MITRE Corporation. All rights reserved.
{"company": "Google", "product": "searching"}
| 166 |
Desire: specify the property names, but
values are variable
 The "enum" keyword specifies both property name and property
value.
 For more flexibility we would like to enumerate the property
names but leave the property values variable.
© 2014 The MITRE Corporation. All rights reserved.
| 167 |
"properties" keyword
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"}
}
}
Instances must be an object. The object may contain a property
"name" and a property "age". The value of "name" must be a string.
The value of "age" must be an integer.
See example22
Do Lab9
© 2014 The MITRE Corporation. All rights reserved.
| 168 |
Sample instance
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"}
}
}
Here is a valid instance:
{
"name": "John Doe",
"age": 30
}
© 2014 The MITRE Corporation. All rights reserved.
| 169 |
Order of properties is irrelevant
{
"name": "John Doe",
"age": 30
}
equivalent instances
{
"age": 30,
"name": "John Doe"
}
© 2014 The MITRE Corporation. All rights reserved.
| 170 |
Property name can be an empty string
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"": {"type": "boolean"}
}
}
Here is a valid instance:
{
"name": "John Doe",
"age": 30,
"": true
}
See example23
© 2014 The MITRE Corporation. All rights reserved.
| 171 |
Properties are optional
 By default, the properties listed in "properties" are optional.
 These are all valid instances:
{
{
"name": "John Doe",
"age": 30,
"": true
{}
"name": "John Doe",
"age": 30
}
}
{
{
"name": "John Doe",
"": true
}
© 2014 The MITRE Corporation. All rights reserved.
"name": "John Doe"
}
| 172 |
Mandate properties using "required"
 The "required" keyword is used to mandate properties.
 The value of "required" is an array of strings, each string
corresponding to the name of a property.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "number" }
},
"required": ["name", "age"]
}
Instances must have "name" and "age" properties.
See example24
© 2014 The MITRE Corporation. All rights reserved.
| 173 |
Object has open content by default
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "number" }
},
"required": ["name", "age"]
}
The schema specifies two properties that must be in
instances. But it doesn’t say there can’t be additional
properties. This is a valid value:
{
"name": "John Doe",
"age": 30,
"height": 68,
additional properties
"married": true
}
© 2014 The MITRE Corporation. All rights reserved.
| 174 |
Sprinkle additional properties anywhere
 In instances "name" and "age" don’t have to come first.
 Additional properties can come before and after them.
 This is a valid instance:
{
"married": true,
"name": "John Doe",
"height": 68,
"age": 30
}
© 2014 The MITRE Corporation. All rights reserved.
| 175 |
"additionalProperties" keyword
Instances can be constrained to contain only those listed in the
schema by using "additionalProperties": false
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "number" }
},
"required": ["name", "age"],
"additionalProperties": false
}
Now instances must contain "name" and
"age" and nothing else.
See example25
© 2014 The MITRE Corporation. All rights reserved.
Do Lab10
| 176 |
Well-constrained object
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20, "pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"required": ["name", "age"],
"additionalProperties": false
}
Instances must contain an object. The object must have exactly
two properties: one named "name" and the other named "age".
The value of "name" must be a string, not longer than 20
characters, consisting of the symbols a-z, A-Z, and space. The
value of "age" must be a number in the range 0 – 120, inclusive.
Nice!
See example26
© 2014 The MITRE Corporation. All rights reserved.
| 177 |
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20, "pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"required": ["name", "age"],
"additionalProperties": false
name and
age are
required
}
© 2014 The MITRE Corporation. All rights reserved.
| 178 |
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20, "pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"required": ["name", "age"],
"additionalProperties": false
No other
properties are
allowed
}
© 2014 The MITRE Corporation. All rights reserved.
| 179 |
The value of name must be a string, with max
length of 20, consisting of a-z, A-Z, and
space.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20, "pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"required": ["name", "age"],
"additionalProperties": false
}
© 2014 The MITRE Corporation. All rights reserved.
| 180 |
The value of age must be a number in the
range 0 – 120, inclusive.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20, "pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"required": ["name", "age"],
"additionalProperties": false
}
© 2014 The MITRE Corporation. All rights reserved.
| 181 |
The instance must be an object.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20, "pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"required": ["name", "age"],
"additionalProperties": false
}
© 2014 The MITRE Corporation. All rights reserved.
| 182 |
Must specify "type": "object" with "properties"
When "properties" is used, then "type": "object" is required to be
present. If it is not present:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"}
}
}
then any value in the instance is valid. For example the following
instance validates against the schema:
true
See example27
© 2014 The MITRE Corporation. All rights reserved.
| 183 |
Here's why
{
"$schema": "http://json-schema.org/draft-04/schema#",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"}
}
}
This schema does not specify the type of value
that an instance must have, so instances can have
any type!
© 2014 The MITRE Corporation. All rights reserved.
| 184 |
Summary of "properties"
The value of "properties" is an object. The object contains
members. Each member has a name and its value is a schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"property-name": JSON Schema,
"property-name": JSON Schema,
...
}
}
© 2014 The MITRE Corporation. All rights reserved.
| 185 |
Recursive definition!
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"property-name": JSON Schema,
"property-name": JSON Schema,
...
}
This JSON
Schema
contains
these JSON
Schemas
}
© 2014 The MITRE Corporation. All rights reserved.
| 186 |
additionalItems versus additionalProperties
Careful! Distinguish between "additionalItems": false and
"additionalProperties": false:
– The former is used to disallow additional items in an array, the
latter is used to disallow additional properties in an object
© 2014 The MITRE Corporation. All rights reserved.
| 187 |
Constraining the number of properties
 The minimum and maximum number of properties can be
constrained using the "minProperties" and "maxProperties"
keywords.
 The following schema specifies a list of activities: bowling,
golfing, and kayaking. At least one activity but not more than
two must be selected for inclusion in a JSON instance:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"bowling": { "type": "string", "maxLength": 20 },
"golfing": { "type": "string", "maxLength": 20 },
"kayaking": { "type": "string", "maxLength": 20 }
},
"minProperties": 1,
"maxProperties": 2,
"additionalProperties": false
}
See example28
© 2014 The MITRE Corporation. All rights reserved.
| 188 |
Sample instance
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"bowling": { "type": "string", "maxLength": 20 },
"golfing": { "type": "string", "maxLength": 20 },
"kayaking": { "type": "string", "maxLength": 20 }
},
"minProperties": 1,
"maxProperties": 2,
"additionalProperties": false
}
This JSON instance is valid since it has two of the activities:
{
"bowling": "50 Lanes",
"kayaking": "Red Rock River"
}
© 2014 The MITRE Corporation. All rights reserved.
| 189 |
Property with { } as its value
 If the value of a property is { } then that property may have any
value.
 The following schema says the value of "name" and "age" can
be anything.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": { },
"age": { }
},
"required": ["name", "age"],
"additionalProperties": false
}
Here is a valid value: {
"name": 12,
"age": false
See example29
© 2014 The MITRE Corporation. All rights reserved.
}
| 190 |
"additionalProperties" (revisited)
 The value of "additionalProperties" may be a boolean, as shown
on the previous slides.
 Or, it may be a JSON Schema:
"additionalProperties": JSON Schema
 Here is an example:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"}
},
"required": ["name", "age"],
"additionalProperties": {
"type": "boolean"
}
}
See example30
© 2014 The MITRE Corporation. All rights reserved.
| 191 |
Additional properties must be booleans
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"}
},
"required": ["name", "age"],
"additionalProperties": {
"type": "boolean"
}
}
The "additionalProperties" specifies: "Instance may have properties
beyond just "name" and "age“. But any additional properties must
have a boolean value."
So, "additionalProperties" (with an object value) is just for specifying
the type of additional properties.
© 2014 The MITRE Corporation. All rights reserved.
| 192 |
Instance containing additional boolean
properties
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"}
},
"required": ["name", "age"],
"additionalProperties": {
"type": "boolean"
}
}
Here is a valid value:
{
"name": "John Doe",
"age": 30,
Notice that each additional property
"married": true,
has a boolean value.
"living": true
}
© 2014 The MITRE Corporation. All rights reserved.
| 193 |
Unlimited number of additional properties
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"}
},
"required": ["name", "age"],
"additionalProperties": {
"type": "boolean"
}
}
As we’ve seen, instances may contain additional boolean properties.
How many? Answer: An unlimited number.
© 2014 The MITRE Corporation. All rights reserved.
| 194 |
Constrain the number of additional properties
using "maxProperties"
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"}
},
"required": ["name", "age"],
"additionalProperties": {
"type": "boolean"
},
"maxProperties": 4
}
Now instances can have, at most, 4 properties.
See example31
© 2014 The MITRE Corporation. All rights reserved.
| 195 |
Valid instances
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"}
},
"required": ["name", "age"],
"additionalProperties": {
{
"type": "boolean"
},
"maxProperties": 4
"name": "John Doe",
"age": 30
}
}
Valid instances: {
3
{
"name": "John Doe",
"age": 30,
"married": true,
"living": true
}
© 2014 The MITRE Corporation. All rights reserved.
"name": "John Doe",
"age": 30,
"married": true,
}
1
2
| 196 |
But this is also a valid instance
{
"name": "John Doe",
"age": 30,
"put-secret-information-in-this-name-field": true,
}
The value of additional
properties are constrained
to boolean
No constraint on the property name!
© 2014 The MITRE Corporation. All rights reserved.
| 197 |
Constrained additional properties
Use the “patternProperties” keyword:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"}
},
"required": ["name", "age"],
"patternProperties": {
"^(married|divorced|living)$": {"type": "boolean"}
},
"additionalProperties": false
}
See example31.1
© 2014 The MITRE Corporation. All rights reserved.
Do Lab11
| 198 |
Regex for the property name
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"}
},
"required": ["name", "age"],
"patternProperties": {
"^(married|divorced|living)$": {"type": "boolean"}
},
"additionalProperties": false
}
Property names must conform to this regular expression (regex)
© 2014 The MITRE Corporation. All rights reserved.
| 199 |
Valid, invalid instance
Valid instance:
{
"name": "John Doe",
"age": 30,
"married": true,
"living": true
}
Invalid instance:
{
"name": "John Doe",
"age": 30,
"put-secret-information-in-this-name-field": true,
}
© 2014 The MITRE Corporation. All rights reserved.
| 200 |
Constraining objects:
If the schema has this:
then the object can be
constrained using this
keyword:
"type": "object"
"enum"
"type": "object",
"properties": { … }
"additionalProperties": false
"type": "object",
"maxProperties"
"properties": { … }
"additionalProperties": JSON Schema
© 2014 The MITRE Corporation. All rights reserved.
| 201 |
Multiple Types
© 2014 The MITRE Corporation. All rights reserved.
| 202 |
Instance may be a boolean or a number
 The value of "type" can be an array of types.
 This schema says that JSON instances must contain either a
boolean value or a number:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": [ "boolean", "number" ]
}
Here are two valid values:
true
12
See example32
Do Lab12
© 2014 The MITRE Corporation. All rights reserved.
| 203 |
Instance may be an array or an object
 This says that JSON instances must be either an array or an
object:
"type": ["array", "object"]
 The following schema constrains the array, if present, to 3
integers in the range 0-100, and constrains the object, if present,
to exactly two properties – name and age – and no others:
Next slide
© 2014 The MITRE Corporation. All rights reserved.
| 204 |
Well-constrained array or object
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": ["array", "object"],
"maxItems": 3,
"items": {
"type": "integer",
"minimum": 0,
"maximum": 100
},
"properties": {
"name": { "type": "string", "maxLength": 20, "pattern": "[a-zA-Z ]+" },
"age": { "type": "integer", "minimum": 0, "maximum": 100 }
},
"required": ["name", "age"],
"additionalProperties": false
}
© 2014 The MITRE Corporation. All rights reserved.
| 205 |
Well-constrained array or object
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": ["array", "object"],
"maxItems": 3,
"items": {
"type": "integer",
"minimum": 0,
"maximum": 100
},
"properties": {
"name": { "type": "string", "maxLength": 20, "pattern": "[a-zA-Z ]+" },
"age": { "type": "integer", "minimum": 0, "maximum": 100 }
},
"required": ["name", "age"],
"additionalProperties": false
}
Here are two valid values:
[12, 3, 99]
{
"name": "John Doe",
"age": 30
See example33
© 2014 The MITRE Corporation. All rights reserved.
}
| 206 |
Annotating Schemas
© 2014 The MITRE Corporation. All rights reserved.
| 207 |
Comments for humans
The "description" keyword is used to provide a human-readable
description. The value of "description" is any string. It is ignored in
validation. The "title" keyword is a short human-readable title.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Short title",
"description": "This description can be arbitrarily long "
}
These keywords may be used in the root schema and in
subschemas.
© 2014 The MITRE Corporation. All rights reserved.
| 208 |
Nice example of using description and title
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "map.feature.plot",
"description": "Plots feature data on the map.",
"type": "object",
"properties": {
"overlayId": {
"description": "The ID of the overlay this feature should be loaded into. If an overlay with this ID already exists, the new
feature is merged into existing overlay; otherwise, a new overlay is created. If no overlayId is included, default overlay with ID equal
to sending widget\u2019s ID is used. If an overlay exists, it will retain its status (whether visible or hidden). If an overlay is created, it
will be made visible.",
"type": "string"
},
"featureId": {
"description": "Unique identifier for the given feature data. Note that feature IDs MUST be unique within a given overlay.
Reusing a feature ID will be considered a reload, with the original feature data being removed and replaced by the new feature
data.",
"type": "string"
},
"name": {
"description": "Name for the given feature data. Note that feature names do not have to be unique and are intended for
display purposes only.",
"type": "string"
},
…
}
}
https://github.com/CMAPI/cmapi-1.2.0/blob/master/channels/map.feature.plot.js
© 2014 The MITRE Corporation. All rights reserved.
| 209 |
Not
© 2014 The MITRE Corporation. All rights reserved.
| 210 |
“Here’s what I don’t want”
 The "not" keyword is used to specify what you don't want.
 This schema says that JSON instances can contain any value,
as long as it's not a string:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"not": { "type": "string" }
}
Here are two valid values:
true
["Hello", "World"]
See example34
Do Lab13
© 2014 The MITRE Corporation. All rights reserved.
| 211 |
Use case: identifier must not be a reserved
word
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"identifier": {
"type": "string",
"maxLength": 20,
"pattern": "^[a-zA-Z][a-zA-Z0-9]*$",
"not": {"enum": ["if", "then", "else", "case", "let", "var"]}
}
}
The value of an identifier
must not be any of these
reserved words:
}
Valid instance:
{
Invalid instance:
{
"identifier": "X"
}
© 2014 The MITRE Corporation. All rights reserved.
"identifier": "if"
}
See example34.1
| 212 |
Use case: ban properties
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"length": { "type": "number", "minimum": 0 },
"width": { "type": "number", "minimum": 0 },
"radius": { "type": "number", "minimum": 0 },
"diameter": { "type": "number", "minimum": 0 }
},
"additionalProperties": false,
"allOf": [
{ "not": {"required": ["radius"]} },
{ "not": {"required": ["diameter"]} }
]
Ban the presence of
radius and diameter
in instances
}
Valid instance:
{
Invalid instance:
{
"length": 10,
"width": 5
}
© 2014 The MITRE Corporation. All rights reserved.
"length": 10,
"radius": 9
}
See example34.2
| 213 |
Repository of schemas
© 2014 The MITRE Corporation. All rights reserved.
| 214 |
Creating a repository of schemas
The "definitions" keyword is used to define a repository of
schemas. The value of "definitions" is a JSON object which
contains one or more properties and the value of each property is
a schema:
"definitions": {
"property1": JSON Schema
"property2": JSON Schema
…
}
© 2014 The MITRE Corporation. All rights reserved.
| 215 |
Repository with 2 schemas
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"person":
{
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20,"pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"required": [ "name", "age" ],
"additionalProperties": false
},
"evens":
{
"type": "number", "multipleOf": 2
}
}
}
See example35
© 2014 The MITRE Corporation. All rights reserved.
2 schemas
| 216 |
Referencing a schema
 The "$ref" keyword is used to reference a schema:
"$ref": reference to a json-schema
 The value of "$ref" is a path expression (very similar to path
expressions in XPath). A json-schema validator replaces "$ref"
and its value by the schema that it references.
© 2014 The MITRE Corporation. All rights reserved.
| 217 |
Internal reference
 The "$ref" in the following schema references the evens
schema.
 The # symbol indicates an internal reference; specifically, it
references the schema within "evens" that is within
"definitions":
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"person":
{
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20,"pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"required": [ "name", "age" ],
"additionalProperties": false
},
"evens":
{
"type": "number", "multipleOf": 2
}
},
"$ref": "#/definitions/evens"
}
© 2014 The MITRE Corporation. All rights reserved.
See example36
Do Lab14
| 218 |
Equivalent
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"person":
{
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20,"pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"required": [ "name", "age" ],
"additionalProperties": false
},
"evens":
{
"type": "number", "multipleOf": 2
}
},
"$ref": "#/definitions/evens"
}
equivalent
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "number",
"multipleOf": 2
}
© 2014 The MITRE Corporation. All rights reserved.
| 219 |
External reference
"$ref" can reference a schema in another document, as shown
here:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "definitions.json#/definitions/evens"
}
© 2014 The MITRE Corporation. All rights reserved.
| 220 |
Reference parent schema
"$ref" can reference any schema, including the schema it is
contained within:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "#"
}
That schema is valid: it validates against the JSON schema-forschemas. However, when a JSON instance is validated against
that schema, an infinite loop error will be generated.
There are schemas which are perfectly
valid but have no conforming instances.
© 2014 The MITRE Corporation. All rights reserved.
| 221 |
Schema-for-schema uses "definitions" and
"$ref"
{
"$schema": "http://json-schema.org/draft-04/schema,
"definitions": {
…
"stringArray": {
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"uniqueItems": true
},
…
"required": { "$ref": "#/definitions/stringArray" },
…
}
© 2014 The MITRE Corporation. All rights reserved.
| 222 |
Schema-for-schema references itself
{
"$schema": "http://json-schema.org/draft-04/schema,
…
"properties": {
"type": "object",
"additionalProperties": { "$ref": "#" },
"default": {}
},
…
}
© 2014 The MITRE Corporation. All rights reserved.
| 223 |
"definitions" can be in a subschema
The "definitions" keyword does not have to be at the root schema
level. It can be embedded in a subschema and then referenced, as
shown here:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"properties": {
"name": { "type": "string", "maxLength": 20,"pattern": "^[a-zA-Z ]*$",
"definitions": {
"evens": { "type": "number", "multipleOf": 2 }
}
},
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"$ref": "#/properties/name/definitions/evens"
}
See example37
© 2014 The MITRE Corporation. All rights reserved.
| 224 |
Where is $ref defined in the specs?
 $ref is defined in a separate document, JSON Reference.
 The JSON Core specification just references it:
http://json-schema.org/latest/json-schema-core.html#anchor26
Here is the JSON Reference specification:
http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03
© 2014 The MITRE Corporation. All rights reserved.
| 225 |
How to reference these values
reference the first array value
{
"foo": ["bar", "baz"],
"": 0,
" ": 7,
reference the value of a property whose
name is the empty string
}
reference the value of a property whose name is a space
© 2014 The MITRE Corporation. All rights reserved.
| 226 |
Here’s how to reference the values
{
"foo": ["bar", "baz"],
"": 0,
" ": 7,
}
#
#/foo
#/foo/0
#/
#/%20
// the whole document
["bar", "baz"]
"bar"
0
7
© 2014 The MITRE Corporation. All rights reserved.
| 227 |
How to reference the first "Name" property?
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Product",
"description": "A product from Acme's catalog",
"type": "object",
"properties": {
"Id": {
"description": "The unique identifier for a product",
"type": "integer"
},
"Name": {
"description": "Name of the product",
"type": "string"
},
"Name": {"type": "integer"},
"Price": {
"type": "number",
"minimum": 0,
"maximum": 10,
"exclusiveMinimum": true
}
},
"additionalProperties": false
}
© 2014 The MITRE Corporation. All rights reserved.
How to reference the value of
this "Name"?
How to reference the
value of this "Name"?
| 228 |
Don’t use duplicate "Name" properties
Although technically it has been argued that JSON allows for
duplicate keys, it is discouraged and many (most?) JSON
parsers will either raise an error or drop one of the values. (Note
that I'm referring to JSON, not JSON Schema). As such, you
should avoid the duplicate "Name" properties in the first place.
Google "JSON duplicate keys" for some good discussions on the
topic.
Chris White
The possibility of having duplicate keys in a JSON object is
widely considered to be a bug in the JSON spec. Most parsers
do not support it (and will silently pick one value or another), and
in the discussion I've seen about updating the JSON standard,
cleaning up this issue by disallowing multiple properties is pretty
uncontroversial.
So basically, don't have multiple "Name" entries in your schema
object. :) This isn't just a JSON Pointer or JSON Schema thing,
but duplicate key names is a very bad idea in JSON data of any
sort.
Geraint David Luff
© 2014 The MITRE Corporation. All rights reserved.
| 229 |
Multiple occurrences of a keyword
 It is okay to have multiple occurrences of the same keyword if
they are in different schemas.
 In the following schema one "maxLength" is in the root schema
and the other is in a subschema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "string",
"maxLength": 5,
"allOf": [
{
"maxLength": 7
}
]
}
© 2014 The MITRE Corporation. All rights reserved.
| 230 |
Multiple occurrences of a keyword
 It is not okay to have multiple occurrences of the same keyword
if they are in the same schema.
 This is not legal:
{
"type": "string",
"pattern": "^\([0-9]{3}\) [0-9]{3}-[0-9]{4}$",
"pattern": "^[0-9]{3}-[0-9]{3}-[0-9]{4}$"
}
© 2014 The MITRE Corporation. All rights reserved.
| 231 |
oneOf
© 2014 The MITRE Corporation. All rights reserved.
| 232 |
Choice of schemas
A choice of schemas can be created using the "oneOf" keyword.
The value of "oneOf" is an array and each item in the array must be
a schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"oneOf": [
JSON Schema,
JSON Schema,
…
]
}
© 2014 The MITRE Corporation. All rights reserved.
| 233 |
Either a number or a boolean
This schema says that a JSON instance must contain either a
number or a boolean:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"oneOf": [
{"type": "number"},
{"type": “boolean"}
]
}
Here are two valid values:
12
true
See example38
Do Lab15
© 2014 The MITRE Corporation. All rights reserved.
| 234 |
Equivalent
{
"$schema": "http://json-schema.org/draft-04/schema#",
"oneOf": [
{"type": "number"},
{"type": “boolean"}
]
}
equivalent
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": [ "boolean", "number" ]
}
© 2014 The MITRE Corporation. All rights reserved.
| 235 |
A multiple of 3 or multiple of 5
This schema says that a JSON instance must contain a number
that is either a multiple of 3 or a multiple of 5:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "number",
"oneOf": [
{ "multipleOf": 3 },
{ "multipleOf": 5 }
]
}
Here are two valid values:
See example39
© 2014 The MITRE Corporation. All rights reserved.
9
10
| 236 |
Content of "oneOf" are schemas?
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "number",
"oneOf": [
{"multipleOf": 3},
{"multipleOf": 5}
]
}
Hold on, those
aren’t schemas
© 2014 The MITRE Corporation. All rights reserved.
| 237 |
Here’s how "oneOf" really works
{
The “base” schema.
The instance must
validate against the
base schema.
© 2014 The MITRE Corporation. All rights reserved.
"$schema": "http://json-schema.org/draft-04/schema#",
A,
"oneOf": [
{ B },
{C}
],
D
}
| 238 |
Here’s how "oneOf" really works
{
The subschemas.
The instance must
validate against one
of the subschemas.
© 2014 The MITRE Corporation. All rights reserved.
"$schema": "http://json-schema.org/draft-04/schema#",
A,
"oneOf": [
{ B },
{C}
],
D
}
| 239 |
Here’s how "oneOf" really works
{
"$schema": "http://json-schema.org/draft-04/schema#",
A,
"oneOf": [
{ B },
{C}
],
D
}
The instance must validate against the base
schema and one of the subschemas.
© 2014 The MITRE Corporation. All rights reserved.
| 240 |
One of the choices can be the empty schema
The following schema says that an instance value must be either
anything or a number:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"oneOf": [
{},
{"type": "number"}
]
}
Here are two valid values:
See example40
© 2014 The MITRE Corporation. All rights reserved.
true
[ "Hello", "World" ]
| 241 |
Is this a valid value?
{
"$schema": "http://json-schema.org/draft-04/schema#",
"oneOf": [
{},
{"type": "number"}
]
}
Is this a valid value?
© 2014 The MITRE Corporation. All rights reserved.
12
| 242 |
No!
 12 is an invalid instance because it matches both schemas
listed in "oneOf"
 An instance must validate against exactly one of the schemas
listed in "oneOf"
© 2014 The MITRE Corporation. All rights reserved.
| 243 |
One of the choices ref’s the parent schema
The following schema is a valid schema:
{
"$schema": "http://json-schema.org/draftv4/schema#",
"oneOf": [
{"type": "number"},
{ "$ref": "#" }
]
}
However, when an instance document is validated against the
schema, the validator will throw an infinite-loop error.
See example41
© 2014 The MITRE Corporation. All rights reserved.
| 244 |
Ref to schemas within "definitions"
This schema says that a JSON instance must contain either a
person object or an even number:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"person": {
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20,"pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"required": [ "name", "age" ],
"additionalProperties": false
},
"evens": { "type": "number", "multipleOf": 2}
},
"oneOf": [
{"$ref": "#/definitions/person"},
{"$ref": "#/definitions/evens"}
]
}
See example42
© 2014 The MITRE Corporation. All rights reserved.
| 245 |
Schema-valid values
Here are two values that validate against the schema on the
previous slide:
12
{
"name": "John Doe",
"age": 30
}
© 2014 The MITRE Corporation. All rights reserved.
| 246 |
Create a schema for this problem
 Instances must contain this property: "common"
 Instances must contain either an "a" property or a "b" property
 So, instances must contain "common" and "a" or "common"
and "b"
 Instances must not contain anything else.
 Create the schema for this.
"common": …
choice
"a": …
"b": …
© 2014 The MITRE Corporation. All rights reserved.
| 247 |
Here’s the schema
{
"type": "object",
"properties": {
"common": { "type": "string" },
"a": { "type": "integer" },
"b": { "type": "integer" }
},
"required":["common"],
"additionalProperties": false,
"oneOf":
[
{ "required": ["a"] },
{ "required": ["b"] }
]
}
See example43
© 2014 The MITRE Corporation. All rights reserved.
| 248 |
allOf
© 2014 The MITRE Corporation. All rights reserved.
| 249 |
Value of the "allOf" keyword
 The value of the "allOf" keyword is an array.
 Each item in the array is a schema.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"allOf": [
JSON Schema,
JSON Schema,
…
]
}
© 2014 The MITRE Corporation. All rights reserved.
| 250 |
The "allOf" keyword
 An instance must validate against the base schema and it must
validate against each schema specified within "allOf".
 Example: the schema on the next slide says that an instance
must conform to the "person" schema and it must have a
"height" property.
© 2014 The MITRE Corporation. All rights reserved.
| 251 |
Instance must conform to 2 subschemas
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"person": {
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20,"pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"required": [ "name", "age" ]
},
"evens": { "type": "number", "multipleOf": 2}
},
"allOf": [
{"$ref": "#/definitions/person"},
Instances must
{
conform to these
"type": "object",
2 subschemas
"properties": {
"height": { "type": "number", "minimum": 0 }
},
"required": [ "height" ]
}
],
"maxProperties": 3
}
© 2014 The MITRE Corporation. All rights reserved.
See example44
| 252 |
Valid instance
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"person": {
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20,"pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"required": [ "name", "age" ]
},
"evens": { "type": "number", "multipleOf": 2}
},
"allOf": [
{"$ref": "#/definitions/person"},
{
"type": "object",
"properties": {
"height": { "type": "number", "minimum": 0 }
},
"required": [ "height" ]
}
],
"maxProperties": 3
}
{
"name": "John Doe",
"age": 30,
"height": 68
}
JSON Schema
Validator
© 2014 The MITRE Corporation. All rights reserved.
valid!
| 253 |
First, validate against the base schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"person": {
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20,"pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"required": [ "name", "age" ]
},
"evens": { "type": "number", "multipleOf": 2}
},
"allOf": [
{"$ref": "#/definitions/person"},
{
"type": "object",
"properties": {
"height": { "type": "number", "minimum": 0 }
},
"required": [ "height" ]
}
],
"maxProperties": 3
}
{
"name": "John Doe",
"age": 30,
"height": 68
}
JSON Schema
Validator
© 2014 The MITRE Corporation. All rights reserved.
valid!
| 254 |
Second, validate against the first subschema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"person": {
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20,"pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"required": [ "name", "age" ]
},
"evens": { "type": "number", "multipleOf": 2}
},
"allOf": [
{"$ref": "#/definitions/person"},
{
"type": "object",
"properties": {
"height": { "type": "number", "minimum": 0 }
},
"required": [ "height" ]
}
],
"maxProperties": 3
}
{
"name": "John Doe",
"age": 30,
"height": 68
}
JSON Schema
Validator
© 2014 The MITRE Corporation. All rights reserved.
valid!
| 255 |
Third, validate against the second
subschema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"person": {
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20,"pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"required": [ "name", "age" ]
},
"evens": { "type": "number", "multipleOf": 2}
},
"allOf": [
{"$ref": "#/definitions/person"},
{
"type": "object",
"properties": {
"height": { "type": "number", "minimum": 0 }
},
"required": [ "height" ]
}
],
"maxProperties": 3
}
{
"name": "John Doe",
"age": 30,
"height": 68
}
JSON Schema
Validator
© 2014 The MITRE Corporation. All rights reserved.
valid!
| 256 |
Instance is valid only if all 3 validations return
“valid”
valid instance =
valid base schema AND
valid subschema1 AND
valid subschema2
Do Lab16
© 2014 The MITRE Corporation. All rights reserved.
| 257 |
No valid instances
This "allOf" lists two subschemas, one specifies that the instance
must be a number while the other specifies that the instance must
be a boolean:
{
"allOf": [
{ "type": "number" },
{ "type": "boolean" }
]
}
No instance can conform to both subschemas since the schema
requires the value be both a number and a boolean, which is
impossible.
© 2014 The MITRE Corporation. All rights reserved.
| 258 |
What instances validate against this schema?
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type" : "object",
"allOf" : [
{ "properties" : {"last_name" : { "type" : "string" }}, "required": ["last_name"] },
{ "properties" : {"first_name" : { "type" : "string" }}, "required": ["first_name"] }
],
"additionalProperties": false
}
See example45
© 2014 The MITRE Corporation. All rights reserved.
| 259 |
The "allOf" keyword
Here is the base schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type" : "object",
"allOf" : [
{ "properties" : {"last_name" : { "type" : "string" }}, "required": ["last_name"] },
{ "properties" : {"first_name" : { "type" : "string" }}, "required": ["first_name"] }
],
"additionalProperties": false
}
Only the empty instance { } validates against the base schema.
© 2014 The MITRE Corporation. All rights reserved.
| 260 |
Instances must validate against 3 schemas
Here are the two subschemas defined within "allOf":
{ "properties" : {"last_name" : { "type" : "string" }}, "required": ["last_name"] }
{ "properties" : {"first_name" : { "type" : "string" }}, "required": ["first_name"] }
An instance must validate against the base schema plus the two
subschemas.
© 2014 The MITRE Corporation. All rights reserved.
| 261 |
This instance doesn’t validate
Consider this instance:
{
"last_name": "Doe",
"first_name": "John"
}
Validating that instance yields the error: "last_name and
first_name are not allowed by the schema."
That's because the base schema does not allow last_name and
first_name.
© 2014 The MITRE Corporation. All rights reserved.
| 262 |
And this instance doesn’t validate
Consider this instance :
{}
then the instance validates against the base schema but not the
subschemas. Validation yields these errors: "object has missing
required properties "last_name" and "object has missing required
properties "first_name".
© 2014 The MITRE Corporation. All rights reserved.
| 263 |
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type" : "object",
"allOf" : [
{ "properties" : {"last_name" : { "type" : "string" }}, "required": ["last_name"] },
{ "properties" : {"first_name" : { "type" : "string" }}, "required": ["first_name"] }
],
"additionalProperties": false
}
This schema has no valid instances!
© 2014 The MITRE Corporation. All rights reserved.
| 264 |
Multiple occurrence​s of the same keyword,
which one wins?
This schema has two "maxLength" keywords:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "string",
"maxLength": 5,
"allOf": [
{
"maxLength": 7
}
]
}
What’s the maximum length of a string: 5 or 7?
See example45.1
© 2014 The MITRE Corporation. All rights reserved.
| 265 |
All constraints must be met
 Both "maxLength" constraints must be met.
 The "maxLength": 5 is part of the base schema, so any data will
be validated against that first. If that holds true, it will then
proceed to "allOf", and the data must also validate against every
schema in the allOf array.
 Good value:
"12345"
 Bad value:
"123456" (too long)
© 2014 The MITRE Corporation. All rights reserved.
| 266 |
anyOf
© 2014 The MITRE Corporation. All rights reserved.
| 267 |
Value of the "anyOf" keyword
 The value of the "anyOf" keyword is an array.
 Each item in the array is a schema.
{
"$schema": "http://json-schema.org/draft-04/schema#",
"anyOf": [
JSON Schema,
JSON Schema,
…
]
}
© 2014 The MITRE Corporation. All rights reserved.
| 268 |
Semantics of the "anyOf" keyword
An instance validates successfully against the "anyOf" keyword if
it validates successfully against at least one schema defined by
this keyword's value.
© 2014 The MITRE Corporation. All rights reserved.
| 269 |
Example schema using "anyOf"
The following schema says that JSON instances can be either a
number or a boolean:
{
"$schema": "http://json-schema.org/draftv4/schema#",
"anyOf": [
{"type": "number"},
{"type": "boolean"}
]
}
Here are two valid values: 12
© 2014 The MITRE Corporation. All rights reserved.
false
| 270 |
"oneOf " versus "anyOf"
{
"$schema": "http://json-schema.org/draft-04/schema#",
"oneOf": [
{},
{"type": "number"}
]
}
12
valid
JSON Schema
Validator
JSON Schema
Validator
invalid
12
See example46
© 2014 The MITRE Corporation. All rights reserved.
{
"$schema": "http://json-schema.org/draft-04/schema#",
“anyOf": [
{},
{"type": "number"}
]
}
| 271 |
"anyOf" specifies required properties
The "anyOf" in the following schema says that JSON instances
must contain a "name" property, an "age" property, or both. And
nothing else:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20,"pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"anyOf": [
{"required": [ "name" ]},
{"required": [ "age" ]}
],
"additionalProperties": false
}
See example47
© 2014 The MITRE Corporation. All rights reserved.
| 272 |
Difference between these schemas?
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20,"pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
}
"additionalProperties": false
}
difference?
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20,"pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"anyOf": [
{"required": [ "name" ]},
{"required": [ "age" ]}
],
"additionalProperties": false
}
© 2014 The MITRE Corporation. All rights reserved.
| 273 |
The difference is with an empty instance
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20,"pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
}
"additionalProperties": false
The empty object { }
is schema-valid
}
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"name": { "type": "string", "maxLength": 20,"pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"anyOf": [
{"required": [ "name" ]},
{"required": [ "age" ]}
],
"additionalProperties": false
}
© 2014 The MITRE Corporation. All rights reserved.
The empty object { }
is not schema-valid
| 274 |
Each subschema must be processable
All subschemas within "anyOf" must be processable by the
validator. Thus, instances will fail validation against the following
schema because the second subschema within "anyOf" contains
an infinite loop (which is not processable):
{
"$schema": "http://json-schema.org/draftv4/schema#",
"anyOf": [
{"type": "number"},
{ "$ref": "#" }
]
}
See example48
© 2014 The MITRE Corporation. All rights reserved.
| 275 |
default
© 2014 The MITRE Corporation. All rights reserved.
| 276 |
The "default" keyword
 The "default" keyword is used to provide a default value.
 The following schema creates an object that has the properties:
"title", "name", and "age".
 The allowable values for "title" is specified using "enum". If a
JSON instance does not contain a "title" the value "Mr" is the
default.
{
default value for "title"
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"title": { "type": "string", "enum": ["Mr", "Mrs", "Miss"], "default": "Mr"},
"name": { "type": "string", "maxLength": 20,"pattern": "^[a-zA-Z ]*$" },
"age": { "type": "number", "minimum": 0, "maximum": 120 }
},
"required": [ "name", "age" ],
"additionalProperties": false
}
See example49
© 2014 The MITRE Corporation. All rights reserved.
| 277 |
"default" is ignored by validators
The value of "default" is ignored by schema validators. So this is a
legal default:
"title": { "type": "string", "enum": ["Mr", "Mrs", "Miss"], "default": "BlahBlah"}
© 2014 The MITRE Corporation. All rights reserved.
| 278 |
Expressing co-constraints
© 2014 The MITRE Corporation. All rights reserved.
| 279 |
Expressing co-constraints
 The "dependencies" keyword enables constraints between
properties (a.k.a. co-constraints) to be expressed.
 Consider properties of these shapes: circle and rectangle. Data
for radius and diameter must be provided for circle. Data for
width and length must be provided for rectangle. So if there is a
radius, there must be a diameter and vice versa. If there is a
width, there must be a length and vice versa.
 The schema on the next slide specifies that radius/diameter and
length/width must always occur in pairs.
© 2014 The MITRE Corporation. All rights reserved.
| 280 |
Co-constraint: “If there is a radius, then there
must be a diameter and vice versa”
{
}
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"length": { "type": "number", "minimum": 0 },
"width": { "type": "number", "minimum": 0 },
"radius": { "type": "number", "minimum": 0 },
"diameter": { "type": "number", "minimum": 0 }
},
"dependencies": {
"radius": ["diameter"],
If the instance has "radius" then
"diameter": ["radius"],
it must also have "diameter"
"length": ["width"],
and vice versa.
"width": ["length"]
},
If the instance has “length" then
"additionalProperties": false
it must also have “width" and
See example50
© 2014 The MITRE Corporation. All rights reserved.
vice versa.
| 281 |
Properties must occur in pairs, or it’s invalid
Here is a valid instance:
{
"length": 10,
"width": 20
}
The following instance is invalid because it has a "length" without
the required "width" property:
{
"length": 10
}
© 2014 The MITRE Corporation. All rights reserved.
| 282 |
Multiple pairs are okay
Note that "dependencies" does not prohibit other properties from
appearing in instances. For example, this is a valid instance:
{
"length": 10,
"width": 5,
"radius": 10,
"diameter": 10
}
© 2014 The MITRE Corporation. All rights reserved.
| 283 |
An array list of dependent properties
The value of "dependencies" is an object; the value of each object
property is an array of strings. The array may contain strings that
are not the name of any property, such as this:
"radius": ["diameter", "Blah"]
If "additionalProperties": false is specified, then "Blah" will not be
allowed in instances and there is a paradox: the schema mandates
that the instance contain "Blah" whenever it contains "radius" but
"additionalProperties": false disallows instances to contain
"Blah".
© 2014 The MITRE Corporation. All rights reserved.
| 284 |
No co-constraint between property and value
 "dependencies" cannot be used to express co-constraints
between properties and values.
 For example, consider a schema with an object that has a
"shape" property and an "enum" with values "circle" or
"rectangle":
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"shape": { "type": "string", "enum": ["circle", "rectangle"] },
"length": { "type": "number", "minimum": 0 },
"width": { "type": "number", "minimum": 0 },
"radius": { "type": "number", "minimum": 0 },
"diameter": { "type": "number", "minimum": 0 }
},
"additionalProperties": false
}
© 2014 The MITRE Corporation. All rights reserved.
It would be useful to express this:
If the value of "shape" is "circle"
then the "radius" and "diameter"
properties must be present.
If the value of "shape" is
"rectangle" then the "width" and
"length" properties must be
present.
However, that capability is not
provided by JSON Schema.
| 285 |
Property versus schema dependency
 We have seen that within "dependencies" you specify a property
with an array value and each item in the array is the name of
another property. This is called a property dependency.
 There is another way to use "dependencies": you specify a
property and the value of it is an object that defines additional
properties. This is called a schema dependency.
© 2014 The MITRE Corporation. All rights reserved.
| 286 |
Example of a schema dependency
The schema on the following slide says:
– If the instance contains the "car" property then the instance must
also contain a "numPassengers" property.
– If the instance contains the "juicers" property then the instance
must also contain a "kind" property.
© 2014 The MITRE Corporation. All rights reserved.
| 287 |
Schema dependency
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"car": { "type": "string", "maxLength": 20 },
"juicer": { "type": "string", "maxLength": 20 }
},
"dependencies": {
"car": {
"type": "object",
"properties": {
If
"numPassengers": { "type": "integer", "minimum": 1 }
},
"required": ["numPassengers"]
},
"juicer": {
"type": "object",
"properties": {
"kind": { "type": "string", "enum": ["press", "centrifugal"] }
},
"required": [“kind"]
}
}
}
See example51
© 2014 The MITRE Corporation. All rights reserved.
"car" then "numPassengers"
If "juicer" then "kind"
| 288 |
Schema-valid instance
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"car": { "type": "string", "maxLength": 20 },
"juicer": { "type": "string", "maxLength": 20 }
},
"dependencies": {
"car": {
"type": "object",
"properties": {
"numPassengers": { "type": "integer", "minimum": 1 }
},
"required": ["numPassengers"]
},
"juicer": {
"type": "object",
"properties": {
"kind": { "type": "string", "enum": ["press", "centrifugal"] }
},
"required": [“kind"]
}
}
}
{
"car": "Toyota Avalon",
"numPassengers": 5
}
JSON Schema
Validator
© 2014 The MITRE Corporation. All rights reserved.
valid!
| 289 |
An instance could also contain "juicer" and
its dependent "kind" property
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"car": { "type": "string", "maxLength": 20 },
"juicer": { "type": "string", "maxLength": 20 }
},
"dependencies": {
"car": {
"type": "object",
"properties": {
"numPassengers": { "type": "integer", "minimum": 1 }
},
"required": ["numPassengers"]
},
"juicer": {
"type": "object",
"properties": {
"kind": { "type": "string", "enum": ["press", "centrifugal"] }
},
"required": [“kind"]
}
}
}
{
"car": "Toyota Avalon",
"numPassengers": 5,
"juicer": "Omega Juicer",
"kind": "centrifugal"
}
JSON Schema
Validator
© 2014 The MITRE Corporation. All rights reserved.
valid!
| 290 |
Constrain the number of properties
If we want to allow just "car" (and its dependent property,
"numPassenger") or "juicer" (and its dependent propert, "kind")
but not both, use "maxProperties": 2 as shown here:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"car": { "type": "string", "maxLength": 20 },
"juicer": { "type": "string", "maxLength": 20 }
},
"maxProperties": 2,
"dependencies": {
"car": {
"type": "object",
"properties": {
"numPassengers": { "type": "integer", "minimum": 1 }
},
"required": ["numPassengers"]
},
"juicer": {
"type": "object",
"properties": {
"kind": { "type": "string", "enum": ["press", "centrifugal"] }
},
"required": [“kind"]
}
}
}
© 2014 The MITRE Corporation. All rights reserved.
Instances can contain no
more than 2 properties.
| 291 |
Recursion
© 2014 The MITRE Corporation. All rights reserved.
| 292 |
Create a schema for this
{
"book": {
"title": "Title 1",
"section": {
"title": "Title 1.1",
"section": {
"title": "Title 1.1.1",
"section": {
"title": "Title 1.1.1.1"
}
}
}
}
}
© 2014 The MITRE Corporation. All rights reserved.
A section contains a title and a section.
See the recursion?
| 293 |
Here’s what we want
title: string
section:
© 2014 The MITRE Corporation. All rights reserved.
| 294 |
Create a recursive "definitions"
"definitions": {
"section": {
"type": "object",
"properties": {
"title": { "type": "string" },
"section": { "$ref": "#/definitions/section" }
},
"required": [ "title" ],
"additionalProperties": false
}
},
© 2014 The MITRE Corporation. All rights reserved.
| 295 |
Create "book" and set its value to point to the
recursive schema
"definitions": {
"section": {
"type": "object",
"properties": {
"title": { "type": "string" },
"section": { "$ref": "#/definitions/section" }
},
"required": [ "title" ],
"additionalProperties": false
}
},
"properties": {
"book": { "$ref": "#/definitions/section" }
}
© 2014 The MITRE Corporation. All rights reserved.
| 296 |
Here’s the schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"section": {
"type": "object",
"properties": {
"title": { "type": "string" },
"section": { "$ref": "#/definitions/section" }
},
"required": [ "title" ],
"additionalProperties": false
}
},
"type": "object",
"properties": {
"book": { "$ref": "#/definitions/section" }
}
}
See example52
© 2014 The MITRE Corporation. All rights reserved.
| 297 |
Unbounded nesting
 The recursive schema on the previous slide allows unbounded
nesting.
 There is no way to limit the amount of nesting or recursion.
© 2014 The MITRE Corporation. All rights reserved.
The End
© 2014 The MITRE Corporation. All rights reserved.