Presentation is loading. Please wait.

Presentation is loading. Please wait.

© 2014 The MITRE Corporation. All rights reserved. JSON and JSON-Schema for XML Developers Roger L. Costello February 5, 2014 Approved for Public Release;

Similar presentations


Presentation on theme: "© 2014 The MITRE Corporation. All rights reserved. JSON and JSON-Schema for XML Developers Roger L. Costello February 5, 2014 Approved for Public Release;"— Presentation transcript:

1 © 2014 The MITRE Corporation. All rights reserved. JSON and JSON-Schema for XML Developers Roger L. Costello February 5, 2014 Approved for Public Release; Distribution Unlimited. Case Number

2 | 2 || 2 | © 2014 The MITRE Corporation. All rights reserved. Trends in XML and JSON usage Based on directory of 11,000 web APIs listed at Programmable Web, December % 70% 60% 50% 40% 30% 20% 10% 0% XML JSON Wow! I better have expertise in both XML and JSON

3 | 3 || 3 | © 2014 The MITRE Corporation. All rights reserved. Specifications The JSON specification is here: –http://www.ecma-international.org/publications/files/ECMA- ST/ECMA-404.pdfhttp://www.ecma-international.org/publications/files/ECMA- ST/ECMA-404.pdf There are two specifications for JSON-Schema –http://json-schema.org/latest/json-schema-core.htmlhttp://json-schema.org/latest/json-schema-core.html –http://json-schema.org/latest/json-schema-validation.htmlhttp://json-schema.org/latest/json-schema-validation.html

4 | 4 || 4 | © 2014 The MITRE Corporation. All rights reserved. Table of Contents  Comparison of XML and JSON  JSON  JSON Schema

5 | 5 || 5 | © 2014 The MITRE Corporation. All rights reserved. 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.

6 | 6 || 6 | © 2014 The MITRE Corporation. All rights reserved. XML is a data format XML is a way of structuring data … XML is a data format.

7 | 7 || 7 | © 2014 The MITRE Corporation. All rights reserved. JSON is a data format JSON is a way of structuring data … JSON is a data format.

8 | 8 || 8 | © 2014 The MITRE Corporation. All rights reserved. Example of XML-formatted data The below XML document contains data about a book: its title, authors, date of publication, and publisher. Parsing Techniques Dick Grune Ceriel J.H. Jacobs 2007 Springer

9 | 9 || 9 | © 2014 The MITRE Corporation. All rights reserved. Same data, JSON-formatted { "Book": { "Title": "Parsing Techniques", "Authors": [ "Dick Grune", "Ceriel J.H. Jacobs" ], "Date": "2007", "Publisher": "Springer" } }

10 | 10 | © 2014 The MITRE Corporation. All rights reserved. XML and JSON, side-by-side Parsing Techniques Dick Grune Ceriel J.H. Jacobs 2007 Springer { "Book": { "Title": "Parsing Techniques", "Authors": [ "Dick Grune", "Ceriel J.H. Jacobs" ], "Date": "2007", "Publisher": "Springer" } }

11 | 11 | © 2014 The MITRE Corporation. All rights reserved. Creating lists in XML and JSON Parsing Techniques Dick Grune Ceriel J.H. Jacobs 2007 Springer { "Book": { "Title": "Parsing Techniques", "Authors": [ "Dick Grune", "Ceriel J.H. Jacobs" ], "Date": "2007", "Publisher": "Springer" } }

12 | 12 | © 2014 The MITRE Corporation. All rights reserved. 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,,, and so forth.

13 | 13 | © 2014 The MITRE Corporation. All rights reserved. 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.

14 | 14 | © 2014 The MITRE Corporation. All rights reserved. An XML document is a tree BookTitle Parsing Techniques AuthorsAuthorDick GruneAuthor Ceriel J.H. Jacobs Date2007PublisherSpringer

15 | 15 | © 2014 The MITRE Corporation. All rights reserved. A JSON Object is a tree BookTitle Parsing Techniques Authors [“Dick Grune”, “Ceriel J.H. Jacobs”] Date2007PublisherSpringer

16 | 16 | © 2014 The MITRE Corporation. All rights reserved. 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.

17 | 17 | © 2014 The MITRE Corporation. All rights reserved. XML Schema for Book

18 | 18 | © 2014 The MITRE Corporation. All rights reserved. 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 }

19 | 19 | © 2014 The MITRE Corporation. All rights reserved. Title with string type { "$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 }

20 | 20 | © 2014 The MITRE Corporation. All rights reserved. Authors list { "$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 }

21 | 21 | © 2014 The MITRE Corporation. All rights reserved. Date with year type { "$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 }

22 | 22 | © 2014 The MITRE Corporation. All rights reserved. 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 } }, "required": ["Book"], "additionalProperties": false }

23 | 23 | © 2014 The MITRE Corporation. All rights reserved. Bootstrap the schema language  An XML Schema is written in XML.  A JSON Schema is written in JSON.

24 | 24 | © 2014 The MITRE Corporation. All rights reserved. Validate XML docs against XML Schema XML Schema XML (instance) XML Schema Validator XML instance is valid/invalid

25 | 25 | © 2014 The MITRE Corporation. All rights reserved. Validate JSON docs against JSON Schema JSON Schema JSON (instance) JSON Schema Validator JSON instance is valid/invalid

26 | 26 | © 2014 The MITRE Corporation. All rights reserved. JSON Schema validators

27 | 27 | © 2014 The MITRE Corporation. All rights reserved. Online JSON Schema validator Paste your JSON Schema in here Paste your JSON in here Click on the validate button Results of validation is shown here

28 | 28 | © 2014 The MITRE Corporation. All rights reserved. Command-line JSON Schema validator Want to validate a JSON instance against a JSON Schema from the command line? Download: json-schema-validator lib.jar from: https://bintray.com/fge/maven/json-schema-validator/view and then, from a command line, type: java -jar json-schema-validator lib.jar schema.json instance.json https://bintray.com/fge/maven/json-schema-validator/view

29 | 29 | © 2014 The MITRE Corporation. All rights reserved. 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 lib.jar from: https://bintray.com/fge/maven/json-schema-validator/view and then read the documentation on the Java API. https://bintray.com/fge/maven/json-schema-validator/view

30 | 30 | © 2014 The MITRE Corporation. All rights reserved. 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! JSON Schema for Schemas JSON Schema JSON Schema Validator JSON Schema is valid/invalid

31 | 31 | © 2014 The MITRE Corporation. All rights reserved. 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/json- schema/FSJmct8crXk https://groups.google.com/forum/#!topic/json- schema/FSJmct8crXk

32 | 32 | © 2014 The MITRE Corporation. All rights reserved. JSON Schema mailing list The Google Group where JSON Schema is discussed: https://groups.google.com/forum/#!forum/json-schemahttps://groups.google.com/forum/#!forum/json-schema

33 | 33 | © 2014 The MITRE Corporation. All rights reserved. JSON used to store location of tweets (Eric Fisher) https://www.mapbox.com/blog/twitter-map-every-tweet/

34 | 34 | © 2014 The MITRE Corporation. All rights reserved. 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

35 | 35 | © 2014 The MITRE Corporation. All rights reserved. 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.

36 | 36 | © 2014 The MITRE Corporation. All rights reserved. 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/ introduction.jsp https://code.google.com/p/google-gson/ introduction.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. gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/g son/stream/JsonReader.html gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/g son/stream/JsonReader.html

37 | 37 | © 2014 The MITRE Corporation. All rights reserved. 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.XSLT  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]

38 | 38 | © 2014 The MITRE Corporation. All rights reserved.

39 | 39 | © 2014 The MITRE Corporation. All rights reserved. Example of XML-to-JSON The online freeformatter.com tool converts this XML: Modern Compiler Design Dick Grune Springer to this JSON: { "MCD", "Title": "Modern Compiler Design", "Author": "Dick Grune", "Publisher": "Springer" } I like that it encodes XML attributes by prefixing the attribute name with symbol.

40 | 40 | © 2014 The MITRE Corporation. All rights reserved. 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 - - builds XML-based news exchange formats for 17 yearswww.iptc.org 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 - - compared to the richer but also more complex XML format - 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: vshttp://www.w3.org/community/odrl/work/json/ Both approaches were welcome and are used - and we learned: an XML-to-JSON tool only is of limited help.

41 | 41 | © 2014 The MITRE Corporation. All rights reserved. The upcoming slides The following slides are organized as follows: –Description of the JSON data format –How to create JSON Schemas

42 © 2014 The MITRE Corporation. All rights reserved. | 42 | The JSON data format

43 | 43 | © 2014 The MITRE Corporation. All rights reserved. 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.

44 | 44 | © 2014 The MITRE Corporation. All rights reserved. JSON object A JSON object is zero or more string-colon-value pairs, separated by comma and wrapped within curly braces: { "name": "John Doe", "age": 30, "married": true } Example of a JSON object:

45 | 45 | © 2014 The MITRE Corporation. All rights reserved. Empty object A JSON object may be empty. This is a JSON object: { }

46 | 46 | © 2014 The MITRE Corporation. All rights reserved. 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: { "name": "John Doe", "age": 30, "married": true, "siblings": ["John", "Mary", "Pat"] } Example of a JSON array

47 | 47 | © 2014 The MITRE Corporation. All rights reserved. Empty array vs. array with a null value [ ] [ null ] Array with no items in it. Array with one item in it.

48 | 48 | © 2014 The MITRE Corporation. All rights reserved. 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" ] } 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 | 49 | © 2014 The MITRE Corporation. All rights reserved. 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"] } Example of a JSON number

50 | 50 | © 2014 The MITRE Corporation. All rights reserved. JSON string A string is a sequence of Unicode characters wrapped within quotes ("). { "name": "John Doe", "age": 30, "married": true, "siblings": ["John", "Mary", "Pat"] } Example of a JSON string

51 | 51 | © 2014 The MITRE Corporation. All rights reserved. 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.

52 | 52 | © 2014 The MITRE Corporation. All rights reserved. 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

53 | 53 | © 2014 The MITRE Corporation. All rights reserved. Expressing characters in hex format A character may be represented as a hexadecimal number, like so: \u006A or \u006a for the 'j' character.

54 | 54 | © 2014 The MITRE Corporation. All rights reserved. No multiline strings JSON does not allow multiline strings.

55 | 55 | © 2014 The MITRE Corporation. All rights reserved. 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!

56 | 56 | © 2014 The MITRE Corporation. All rights reserved. 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"] } Example of a JSON boolean

57 | 57 | © 2014 The MITRE Corporation. All rights reserved. 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" }

58 | 58 | © 2014 The MITRE Corporation. All rights reserved. This is a legal JSON instance 42

59 | 59 | © 2014 The MITRE Corporation. All rights reserved. so is this "Hello World"

60 | 60 | © 2014 The MITRE Corporation. All rights reserved. and so is this true

61 | 61 | © 2014 The MITRE Corporation. All rights reserved. and this [ true, null, 12, "ABC" ]

62 | 62 | © 2014 The MITRE Corporation. All rights reserved. Whitespace is irrelevant { "name": "John Doe", "age": 30, "married": true } equivalent

63 | 63 | © 2014 The MITRE Corporation. All rights reserved. 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.

64 | 64 | © 2014 The MITRE Corporation. All rights reserved. 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!

65 | 65 | © 2014 The MITRE Corporation. All rights reserved. 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"} ] } }

66 | 66 | © 2014 The MITRE Corporation. All rights reserved. Extend, ad infinitum { "Book": { "Title": "Parsing Techniques", "Authors": [ {"name": {"first":"Dick", "last":"Grune"}, "university": "Vrije Universiteit"}, {"name": {"first":"Ceriel", "last":"Jacobs"}, "university": "Vrije Universiteit"} ] } }

67 | 67 | © 2014 The MITRE Corporation. All rights reserved. 7 simple JSON components, assemble to generate unlimited complexity Array Object Number String Boolean Null Integer

68 | 68 | © 2014 The MITRE Corporation. All rights reserved. JSON provides the structures and assembly rules, you customize them for your needs { "___": json-value, "___": json-value, "___": json-value, … } object [ json-value, json-value, json-value, … ] array "___" string

69 | 69 | © 2014 The MITRE Corporation. All rights reserved. JSON provides the structures and assembly rules, you customize them for your needs { "___": json-value, "___": json-value, "___": json-value, … } object [ json-value, json-value, json-value, … ] array "___" string structures

70 | 70 | © 2014 The MITRE Corporation. All rights reserved. JSON provides the structures and assembly rules, you customize them for your needs { "___": json-value, "___": json-value, "___": json-value, … } object [ json-value, json-value, json-value, … ] array "___" string assembly points

71 | 71 | © 2014 The MITRE Corporation. All rights reserved. JSON provides the structures and assembly rules, you customize them for your needs { "___": json-value, "___": json-value, "___": json-value, … } object [ json-value, json-value, json-value, … ] array "___" string customize

72 | 72 | © 2014 The MITRE Corporation. All rights reserved. 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!

73 | 73 | © 2014 The MITRE Corporation. All rights reserved. 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  Here's a YouTube presentation on how to create JSON Schemas using Visual Studio: https://www.youtube.com/watch?v=Jt5SCNC87d4 https://www.youtube.com/watch?v=Jt5SCNC87d4 Do Lab2

74 | 74 | © 2014 The MITRE Corporation. All rights reserved. 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 

75 | 75 | © 2014 The MITRE Corporation. All rights reserved. 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 domain- specific 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.

76 | 76 | © 2014 The MITRE Corporation. All rights reserved. Generating railroad diagrams  I love the railroad diagrams which are used to represent the JSON language. What tool is used to generate these diagrams?railroad 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.Online Railroad Diagram Generator syntax diagrams context-free grammarsEBNF  You have to type in the grammar and it'll make the diagram.

77 | 77 | © 2014 The MITRE Corporation. All rights reserved. Generating railroad diagrams For example, to create the railroad diagram for a JSON object, you would use the code: object ::= '{' ((string ':' value ) ( ',' string ':' value )*)? '}'

78 | 78 | © 2014 The MITRE Corporation. All rights reserved. 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. "phoneNumbers": [ " ", " " ]

79 | 79 | © 2014 The MITRE Corporation. All rights reserved. xml2json XML Shell (xmlsh, provides a capability to convert XML to JSON:

80 © 2014 The MITRE Corporation. All rights reserved. | 80 | How to create JSON Schemas

81 | 81 | © 2014 The MITRE Corporation. All rights reserved. A contract for data exchanges Both XML Schema and JSON Schema may be used as a contract for data exchanges: data Contract (schema) conforms to

82 | 82 | © 2014 The MITRE Corporation. All rights reserved. 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 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 Closed Content: instance documents can contain only those items specified by the schema. Definition of Open Content: instance documents can contain items above and beyond those specified by the schema.

83 | 83 | © 2014 The MITRE Corporation. All rights reserved. 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.

84 | 84 | © 2014 The MITRE Corporation. All rights reserved. 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

85 | 85 | © 2014 The MITRE Corporation. All rights reserved. A JSON Schema is a JSON object { "keyword": value, "keyword": value, "keyword": value, … }

86 | 86 | © 2014 The MITRE Corporation. All rights reserved. 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.

87 | 87 | © 2014 The MITRE Corporation. All rights reserved. Empty schema { } This is a valid JSON Schema! It places no restrictions on JSON instances.

88 | 88 | © 2014 The MITRE Corporation. All rights reserved. Every JSON instance is valid! { } JSON instance JSON Schema Validator Valid! Do Lab3

89 | 89 | © 2014 The MITRE Corporation. All rights reserved. " $schema " keyword { "$schema": "http://json-schema.org/draft-04/schema#", … }

90 | 90 | © 2014 The MITRE Corporation. All rights reserved. " $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

91 | 91 | © 2014 The MITRE Corporation. All rights reserved. " type " keyword { "$schema": "http://json-schema.org/draft-04/schema#", "type": "type", … }

92 | 92 | © 2014 The MITRE Corporation. All rights reserved. " 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 "

93 | 93 | © 2014 The MITRE Corporation. All rights reserved. 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 ).

94 | 94 | © 2014 The MITRE Corporation. All rights reserved. Only boolean instances are valid { "$schema": "http://json-schema.org/draft-04/schema#", "type": "boolean" } true JSON Schema Validator Valid!

95 | 95 | © 2014 The MITRE Corporation. All rights reserved. String instances are not valid { "$schema": "http://json-schema.org/draft-04/schema#", "type": "boolean" } " Hello World " JSON Schema Validator Not valid!

96 | 96 | © 2014 The MITRE Corporation. All rights reserved. Alert! "true" is not a Boolean value { "$schema": "http://json-schema.org/draft-04/schema#", "type": "boolean" } " true " JSON Schema Validator Not valid!

97 | 97 | © 2014 The MITRE Corporation. All rights reserved. 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:  Copy to the clipboard the content of instance.json and then paste it into the Data section.  Press the validate button.

98 | 98 | © 2014 The MITRE Corporation. All rights reserved. Paste schema here Paste instance here Press the Validate button Instance is valid!

99 | 99 | © 2014 The MITRE Corporation. All rights reserved. Order of keywords is irrelevant { "$schema": "http://json-schema.org/draft-04/schema#", "type": "boolean" } { "type": "boolean", "$schema": "http://json-schema.org/draft-04/schema#" } equivalent!

100 | 100 | © 2014 The MITRE Corporation. All rights reserved. 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).

101 | 101 | © 2014 The MITRE Corporation. All rights reserved. Only numeric instances are valid { "$schema": "http://json-schema.org/draft-04/schema#", "type": "number" } 12.3 JSON Schema Validator Valid!

102 | 102 | © 2014 The MITRE Corporation. All rights reserved. Examples of numeric values e E x 10 3

103 | 103 | © 2014 The MITRE Corporation. All rights reserved. " 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

104 | 104 | © 2014 The MITRE Corporation. All rights reserved. " 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 }

105 | 105 | © 2014 The MITRE Corporation. All rights reserved. " 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

106 | 106 | © 2014 The MITRE Corporation. All rights reserved. " 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 } See example04 Here are four schema-valid values:

107 | 107 | © 2014 The MITRE Corporation. All rights reserved. " multipleOf " value The value of "multipleOf" must be greater than 0 (no negative numbers).

108 | 108 | © 2014 The MITRE Corporation. All rights reserved. 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:

109 | 109 | © 2014 The MITRE Corporation. All rights reserved. Number constraints also apply to integer The constraints that apply to "number" also apply to "integer": –enum –minimum –maximum –exclusiveMinimum –exclusiveMaximum –multipleOf Do Lab4

110 | 110 | © 2014 The MITRE Corporation. All rights reserved. String type { "$schema": "http://json-schema.org/draft-04/schema#", "type": "string" } This schema constrains instances to contain only a string.

111 | 111 | © 2014 The MITRE Corporation. All rights reserved. " 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 } See example05 Here is a schema-valid value: "Hello World"

112 | 112 | © 2014 The MITRE Corporation. All rights reserved. Value of " maxLength " { "$schema": "http://json-schema.org/draft-04/schema#", "type": "string", "maxLength": ___ } Must be an integer, ≥ 0

113 | 113 | © 2014 The MITRE Corporation. All rights reserved. " 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 }

114 | 114 | © 2014 The MITRE Corporation. All rights reserved. " 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.

115 | 115 | © 2014 The MITRE Corporation. All rights reserved. " 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 start with the letters of the alphabet plus space. This symbol indicates that a string must end with the letters of the alphabet plus space.

116 | 116 | © 2014 The MITRE Corporation. All rights reserved. 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. ”

117 | 117 | © 2014 The MITRE Corporation. All rights reserved. Components of regular expressions Basic patternMatching string x The character x.Any character, except newline [ xyz... ]Any of the characters, x, y, z, … Repetition operators: R?R is optional (zero or one occurrence) R*Zero or more occurrences of R R+One or more occurrences of R Compositional operators: R1R2R1R2 An R 1 followed by an R 2 R 1 |R 2 Either an R 1 or an R 2 Grouping: (R)R itself Acknowledgement: This table comes from Modern Compiler Design by Grune et al, p62. Legend: x, y, z, … stand for any character R, R 1, R 2, …stand for any regular expression Operator Precedence: Repetition operators have the highest precedence (bind most tightly); next comes the concatenation operator; and the alternatives operator | has the lowest precedence

118 | 118 | © 2014 The MITRE Corporation. All rights reserved. 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-of- characters”. Here’s how to express it: \\-

119 | 119 | © 2014 The MITRE Corporation. All rights reserved. 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"] } See example07 Here’s a schema-valid instance: "red"

120 | 120 | © 2014 The MITRE Corporation. All rights reserved. "enum" applies to all types The "enum" keyword can be used with all seven types.

121 | 121 | © 2014 The MITRE Corporation. All rights reserved. "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] }

122 | 122 | © 2014 The MITRE Corporation. All rights reserved. " 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" } See example08 Here’s a schema-valid instance: " T12:50:00Z"

123 | 123 | © 2014 The MITRE Corporation. All rights reserved. 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

124 | 124 | © 2014 The MITRE Corporation. All rights reserved. " format " keyword values  Here are the valid values for the "format" keyword: –"date-time" –" " –"hostname" –"ipv4" –"uri"  Those values are called format attributes.  The "format" keyword may only be used with the string type.

125 | 125 | © 2014 The MITRE Corporation. All rights reserved. Examples of " format " values  "date-time" " T12:50:00Z"  " "  "hostname" "www.google.com"  "ipv4" " "  "uri" "http://www.google.com" Do Lab5

126 © 2014 The MITRE Corporation. All rights reserved. | 126 | Array

127 | 127 | © 2014 The MITRE Corporation. All rights reserved. Array type { "$schema": "http://json-schema.org/draft-04/schema#", "type": "array" }

128 | 128 | © 2014 The MITRE Corporation. All rights reserved. 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]

129 | 129 | © 2014 The MITRE Corporation. All rights reserved. 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]] } See example09 Here are the only two valid instance values: ["A", "B"] [1,2,3]

130 | 130 | © 2014 The MITRE Corporation. All rights reserved. " 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 } See example10 Here’s a schema-valid instance: [ 1, true, ["A", "B"] ]

131 | 131 | © 2014 The MITRE Corporation. All rights reserved. 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.

132 | 132 | © 2014 The MITRE Corporation. All rights reserved. " 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 }

133 | 133 | © 2014 The MITRE Corporation. All rights reserved. Recursive definition! { "$schema": "http://json-schema.org/draft-04/schema#", "type": "array", "maxItems": 3, "items": JSON Schema } This JSON Schema contains this JSON Schema

134 | 134 | © 2014 The MITRE Corporation. All rights reserved. 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.

135 | 135 | © 2014 The MITRE Corporation. All rights reserved. Terminology: root schema, subschema subschema { "$schema": "http://json-schema.org/draft-04/schema#", "type": "array", "maxItems": 3, "items": { "keyword": value, "keyword": value, "keyword": value, … } } root schema { "keyword": value, "keyword": value, "keyword": value, … }

136 | 136 | © 2014 The MITRE Corporation. All rights reserved. Don’t use $schema in subschemas { "$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 Yes "$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

137 | 137 | © 2014 The MITRE Corporation. All rights reserved. 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.

138 | 138 | © 2014 The MITRE Corporation. All rights reserved. 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" } } See example11 Here are four schema-valid instances: [1,2,3] [1,2] [1] [ ]

139 | 139 | © 2014 The MITRE Corporation. All rights reserved. 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

140 | 140 | © 2014 The MITRE Corporation. All rights reserved. " 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 } See example13 The default value of "uniqueItems" is false.

141 | 141 | © 2014 The MITRE Corporation. All rights reserved. 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

142 | 142 | © 2014 The MITRE Corporation. All rights reserved. " 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": {} } See example15 Here is a schema-valid instance: [ "hello world", 12, {"age":30} ]

143 | 143 | © 2014 The MITRE Corporation. All rights reserved. Equivalent! { "$schema": "http://json-schema.org/draft-04/schema#", "type": "array", "maxItems": 3, "items": {} } { "$schema": "http://json-schema.org/draft-04/schema#", "type": "array", "maxItems": 3 } Equivalent since the default value of "items" is { }

144 | 144 | © 2014 The MITRE Corporation. All rights reserved. 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, … ] } This kind of array is called an array tuple

145 | 145 | © 2014 The MITRE Corporation. All rights reserved. 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"] } ] }

146 | 146 | © 2014 The MITRE Corporation. All rights reserved. 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

147 | 147 | © 2014 The MITRE Corporation. All rights reserved. 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

148 | 148 | © 2014 The MITRE Corporation. All rights reserved. "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

149 | 149 | © 2014 The MITRE Corporation. All rights reserved. Array tuple with { } for each value { "$schema": "http://json-schema.org/draft-04/schema#", "type": "array", "items": [ {}, {} ], "additionalItems": false } See example18 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] [1, true] [1, [1, true]]

150 | 150 | © 2014 The MITRE Corporation. All rights reserved. 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)

151 | 151 | © 2014 The MITRE Corporation. All rights reserved. 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

152 | 152 | © 2014 The MITRE Corporation. All rights reserved. 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"} } See example19 Here are three valid instances: ["Hello World", true, false, false, true] ["Hello World"] [ ]

153 | 153 | © 2014 The MITRE Corporation. All rights reserved. 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

154 | 154 | © 2014 The MITRE Corporation. All rights reserved. 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: [ ] ["Hello World"] ["Hello World", true] ["Hello World", true, false] These are not schema-valid: [true] ["Hello World", true, false, false]

155 | 155 | © 2014 The MITRE Corporation. All rights reserved. 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).

156 | 156 | © 2014 The MITRE Corporation. All rights reserved. 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"] } ] } { "$schema": "http://json-schema.org/draft-04/schema#", "type": "array", "items": [ { "type": "string", "enum": ["white", "black"] }, { "type": "string", "enum": ["cup", "plate"] } ], "additionalItems": { } } Equivalent The array may contain zero or more additional items and each additional item may have any value.

157 | 157 | © 2014 The MITRE Corporation. All rights reserved. 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"

158 | 158 | © 2014 The MITRE Corporation. All rights reserved. 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"

159 | 159 | © 2014 The MITRE Corporation. All rights reserved. The value of additionalItems is a choice "additionalItems": "type": "boolean" JSON Schema

160 | 160 | © 2014 The MITRE Corporation. All rights reserved. Here is how the schema-for-schema defines "additionalItems" "additionalItems": { "anyOf": [ { "type": "boolean" }, { "$ref": "#" } ], "default": {} },

161 © 2014 The MITRE Corporation. All rights reserved. | 161 | Object

162 | 162 | © 2014 The MITRE Corporation. All rights reserved. Object type { "$schema": "http://json-schema.org/draft-04/schema#", "type": "object" }

163 | 163 | © 2014 The MITRE Corporation. All rights reserved. Object type { "$schema": "http://json-schema.org/draft-04/schema#", "type": "object" } The schema constrains instances to contain only an object. { "X": 12, "Y": "hello" } See example20 Here’s a schema-valid value:

164 | 164 | © 2014 The MITRE Corporation. All rights reserved. Unconstrained object The schema specifies no constraints on the object's properties (i.e., name/value pairs). { "$schema": "http://json-schema.org/draft-04/schema#", "type": "object" }

165 | 165 | © 2014 The MITRE Corporation. All rights reserved. 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} {"company": "Google", "product": "searching"} See example21

166 | 166 | © 2014 The MITRE Corporation. All rights reserved. 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.

167 | 167 | © 2014 The MITRE Corporation. All rights reserved. "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

168 | 168 | © 2014 The MITRE Corporation. All rights reserved. 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 }

169 | 169 | © 2014 The MITRE Corporation. All rights reserved. Order of properties is irrelevant { "name": "John Doe", "age": 30 } { "age": 30, "name": "John Doe" } equivalent instances

170 | 170 | © 2014 The MITRE Corporation. All rights reserved. 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: See example23 { "name": "John Doe", "age": 30, "": true }

171 | 171 | © 2014 The MITRE Corporation. All rights reserved. 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 } { "name": "John Doe" } { }

172 | 172 | © 2014 The MITRE Corporation. All rights reserved. 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"] } See example24 Instances must have "name" and "age" properties.

173 | 173 | © 2014 The MITRE Corporation. All rights reserved. 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: additional properties { "name": "John Doe", "age": 30, "height": 68, "married": true }

174 | 174 | © 2014 The MITRE Corporation. All rights reserved. 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 }

175 | 175 | © 2014 The MITRE Corporation. All rights reserved. "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 Do Lab10

176 | 176 | © 2014 The MITRE Corporation. All rights reserved. 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 } See example26 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!

177 | 177 | © 2014 The MITRE Corporation. All rights reserved. { "$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

178 | 178 | © 2014 The MITRE Corporation. All rights reserved. { "$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

179 | 179 | © 2014 The MITRE Corporation. All rights reserved. { "$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 } The value of name must be a string, with max length of 20, consisting of a-z, A-Z, and space.

180 | 180 | © 2014 The MITRE Corporation. All rights reserved. { "$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 } The value of age must be a number in the range 0 – 120, inclusive.

181 | 181 | © 2014 The MITRE Corporation. All rights reserved. { "$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 } The instance must be an object.

182 | 182 | © 2014 The MITRE Corporation. All rights reserved. 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

183 | 183 | © 2014 The MITRE Corporation. All rights reserved. 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!

184 | 184 | © 2014 The MITRE Corporation. All rights reserved. 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,... } }

185 | 185 | © 2014 The MITRE Corporation. All rights reserved. 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

186 | 186 | © 2014 The MITRE Corporation. All rights reserved. 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

187 | 187 | © 2014 The MITRE Corporation. All rights reserved. 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

188 | 188 | © 2014 The MITRE Corporation. All rights reserved. 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" }

189 | 189 | © 2014 The MITRE Corporation. All rights reserved. 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 } See example29 Here is a valid value: { "name": 12, "age": false }

190 | 190 | © 2014 The MITRE Corporation. All rights reserved. "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

191 | 191 | © 2014 The MITRE Corporation. All rights reserved. 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.

192 | 192 | © 2014 The MITRE Corporation. All rights reserved. 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, "married": true, "living": true } Notice that each additional property has a boolean value.

193 | 193 | © 2014 The MITRE Corporation. All rights reserved. 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.

194 | 194 | © 2014 The MITRE Corporation. All rights reserved. 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

195 | 195 | © 2014 The MITRE Corporation. All rights reserved. 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 } Valid instances: { "name": "John Doe", "age": 30, "married": true, "living": true } { "name": "John Doe", "age": 30, "married": true, } { "name": "John Doe", "age": 30 } 1 2 3

196 | 196 | © 2014 The MITRE Corporation. All rights reserved. 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!

197 | 197 | © 2014 The MITRE Corporation. All rights reserved. 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 Do Lab11

198 | 198 | © 2014 The MITRE Corporation. All rights reserved. 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)

199 | 199 | © 2014 The MITRE Corporation. All rights reserved. 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, }

200 | 200 | © 2014 The MITRE Corporation. All rights reserved. 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", "properties": { … } "additionalProperties": JSON Schema "maxProperties"

201 © 2014 The MITRE Corporation. All rights reserved. | 201 | Multiple Types

202 | 202 | © 2014 The MITRE Corporation. All rights reserved. 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" ] } See example32 Here are two valid values: true12 Do Lab12

203 | 203 | © 2014 The MITRE Corporation. All rights reserved. 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

204 | 204 | © 2014 The MITRE Corporation. All rights reserved. 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 }

205 | 205 | © 2014 The MITRE Corporation. All rights reserved. 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 } See example33 Here are two valid values: [12, 3, 99] { "name": "John Doe", "age": 30 }

206 © 2014 The MITRE Corporation. All rights reserved. | 206 | Annotating Schemas

207 | 207 | © 2014 The MITRE Corporation. All rights reserved. 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.

208 | 208 | © 2014 The MITRE Corporation. All rights reserved. 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

209 © 2014 The MITRE Corporation. All rights reserved. | 209 | Not

210 | 210 | © 2014 The MITRE Corporation. All rights reserved. “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" } } See example34 Here are two valid values: true["Hello", "World"] Do Lab13

211 | 211 | © 2014 The MITRE Corporation. All rights reserved. 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: See example34.1 { "identifier": "X" } Valid instance: { "identifier": "if" } Invalid instance:

212 | 212 | © 2014 The MITRE Corporation. All rights reserved. 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 { "length": 10, "width": 5 } Valid instance: { "length": 10, "radius": 9 } Invalid instance: See example34.2

213 © 2014 The MITRE Corporation. All rights reserved. | 213 | Repository of schemas

214 | 214 | © 2014 The MITRE Corporation. All rights reserved. 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 … }

215 | 215 | © 2014 The MITRE Corporation. All rights reserved. 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 2 schemas

216 | 216 | © 2014 The MITRE Corporation. All rights reserved. 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.

217 | 217 | © 2014 The MITRE Corporation. All rights reserved. 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" } See example36 Do Lab14

218 | 218 | © 2014 The MITRE Corporation. All rights reserved. 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" } { "$schema": "http://json-schema.org/draft-04/schema#", "type": "number", "multipleOf": 2 } equivalent

219 | 219 | © 2014 The MITRE Corporation. All rights reserved. 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" }

220 | 220 | © 2014 The MITRE Corporation. All rights reserved. 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-for- schemas. 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.

221 | 221 | © 2014 The MITRE Corporation. All rights reserved. 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" }, … }

222 | 222 | © 2014 The MITRE Corporation. All rights reserved. Schema-for-schema references itself { "$schema": "http://json-schema.org/draft-04/schema, … "properties": { "type": "object", "additionalProperties": { "$ref": "#" }, "default": {} }, … }

223 | 223 | © 2014 The MITRE Corporation. All rights reserved. "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

224 | 224 | © 2014 The MITRE Corporation. All rights reserved. Where is $ref defined in the specs?  $ref is defined in a separate document, JSON Reference.  The JSON Core specification just references it: Here is the JSON Reference specification:

225 | 225 | © 2014 The MITRE Corporation. All rights reserved. How to reference these values { "foo": ["bar", "baz"], "": 0, " ": 7, } reference the first array value reference the value of a property whose name is the empty string reference the value of a property whose name is a space

226 | 226 | © 2014 The MITRE Corporation. All rights reserved. Here’s how to reference the values { "foo": ["bar", "baz"], "": 0, " ": 7, } # // the whole document #/foo ["bar", "baz"] #/foo/0 "bar" #/ 0 #/%20 7

227 | 227 | © 2014 The MITRE Corporation. All rights reserved. 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 } How to reference the value of this "Name"?

228 | 228 | © 2014 The MITRE Corporation. All rights reserved. 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

229 | 229 | © 2014 The MITRE Corporation. All rights reserved. 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 } ] }http://json-schema.org/draft-04/schema#

230 | 230 | © 2014 The MITRE Corporation. All rights reserved. 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}$" }

231 © 2014 The MITRE Corporation. All rights reserved. | 231 | oneOf

232 | 232 | © 2014 The MITRE Corporation. All rights reserved. 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, … ] }

233 | 233 | © 2014 The MITRE Corporation. All rights reserved. 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"} ] } See example38 Here are two valid values: 12true Do Lab15

234 | 234 | © 2014 The MITRE Corporation. All rights reserved. Equivalent { "$schema": "http://json-schema.org/draft-04/schema#", "oneOf": [ {"type": "number"}, {"type": “boolean"} ] } { "$schema": "http://json-schema.org/draft-04/schema#", "type": [ "boolean", "number" ] } equivalent

235 | 235 | © 2014 The MITRE Corporation. All rights reserved. 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: 910 See example39

236 | 236 | © 2014 The MITRE Corporation. All rights reserved. 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

237 | 237 | © 2014 The MITRE Corporation. All rights reserved. Here’s how "oneOf" really works { "$schema": "http://json-schema.org/draft-04/schema#", A, "oneOf": [ { B }, { C } ], D } The “base” schema. The instance must validate against the base schema.

238 | 238 | © 2014 The MITRE Corporation. All rights reserved. Here’s how "oneOf" really works { "$schema": "http://json-schema.org/draft-04/schema#", A, "oneOf": [ { B }, { C } ], D } The subschemas. The instance must validate against one of the subschemas.

239 | 239 | © 2014 The MITRE Corporation. All rights reserved. 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.

240 | 240 | © 2014 The MITRE Corporation. All rights reserved. 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: true[ "Hello", "World" ] See example40

241 | 241 | © 2014 The MITRE Corporation. All rights reserved. Is this a valid value? { "$schema": "http://json-schema.org/draft-04/schema#", "oneOf": [ {}, {"type": "number"} ] } Is this a valid value? 12

242 | 242 | © 2014 The MITRE Corporation. All rights reserved. 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"

243 | 243 | © 2014 The MITRE Corporation. All rights reserved. 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": "#" } ] } See example41 However, when an instance document is validated against the schema, the validator will throw an infinite-loop error.

244 | 244 | © 2014 The MITRE Corporation. All rights reserved. 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

245 | 245 | © 2014 The MITRE Corporation. All rights reserved. Schema-valid values Here are two values that validate against the schema on the previous slide: 12 { "name": "John Doe", "age": 30 }

246 | 246 | © 2014 The MITRE Corporation. All rights reserved. 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": … "a": … "b": … choice

247 | 247 | © 2014 The MITRE Corporation. All rights reserved. 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

248 © 2014 The MITRE Corporation. All rights reserved. | 248 | allOf

249 | 249 | © 2014 The MITRE Corporation. All rights reserved. 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, … ] }

250 | 250 | © 2014 The MITRE Corporation. All rights reserved. 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.

251 | 251 | © 2014 The MITRE Corporation. All rights reserved. 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"}, { "type": "object", "properties": { "height": { "type": "number", "minimum": 0 } }, "required": [ "height" ] } ], "maxProperties": 3 } See example44 Instances must conform to these 2 subschemas

252 | 252 | © 2014 The MITRE Corporation. All rights reserved. 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 valid!

253 | 253 | © 2014 The MITRE Corporation. All rights reserved. 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 valid!

254 | 254 | © 2014 The MITRE Corporation. All rights reserved. Second, validate against the first subschema { "name": "John Doe", "age": 30, "height": 68 } JSON Schema Validator valid! { "$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 }

255 | 255 | © 2014 The MITRE Corporation. All rights reserved. Third, validate against the second subschema { "name": "John Doe", "age": 30, "height": 68 } JSON Schema Validator valid! { "$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 }

256 | 256 | © 2014 The MITRE Corporation. All rights reserved. Instance is valid only if all 3 validations return “valid” valid instance =valid base schema AND valid subschema1 AND valid subschema2 Do Lab16

257 | 257 | © 2014 The MITRE Corporation. All rights reserved. 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.

258 | 258 | © 2014 The MITRE Corporation. All rights reserved. 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 }http://json-schema.org/draft-04/schema# See example45

259 | 259 | © 2014 The MITRE Corporation. All rights reserved. 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 }http://json-schema.org/draft-04/schema# Only the empty instance { } validates against the base schema.

260 | 260 | © 2014 The MITRE Corporation. All rights reserved. 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.

261 | 261 | © 2014 The MITRE Corporation. All rights reserved. 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.

262 | 262 | © 2014 The MITRE Corporation. All rights reserved. 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".

263 | 263 | © 2014 The MITRE Corporation. All rights reserved. This schema has no valid instances! { "$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 }http://json-schema.org/draft-04/schema#

264 | 264 | © 2014 The MITRE Corporation. All rights reserved. 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

265 | 265 | © 2014 The MITRE Corporation. All rights reserved. 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)

266 © 2014 The MITRE Corporation. All rights reserved. | 266 | anyOf

267 | 267 | © 2014 The MITRE Corporation. All rights reserved. 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, … ] }

268 | 268 | © 2014 The MITRE Corporation. All rights reserved. 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.

269 | 269 | © 2014 The MITRE Corporation. All rights reserved. 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: 12false

270 | 270 | © 2014 The MITRE Corporation. All rights reserved. "oneOf " versus "anyOf" { "$schema": "http://json-schema.org/draft-04/schema#", "oneOf": [ {}, {"type": "number"} ] } 12 JSON Schema Validator invalid { "$schema": "http://json-schema.org/draft-04/schema#", “anyOf": [ {}, {"type": "number"} ] } 12 JSON Schema Validator valid See example46

271 | 271 | © 2014 The MITRE Corporation. All rights reserved. "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

272 | 272 | © 2014 The MITRE Corporation. All rights reserved. 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 } }, "anyOf": [ {"required": [ "name" ]}, {"required": [ "age" ]} ], "additionalProperties": false } { "$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?

273 | 273 | © 2014 The MITRE Corporation. All rights reserved. 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 } }, "anyOf": [ {"required": [ "name" ]}, {"required": [ "age" ]} ], "additionalProperties": false } { "$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 The empty object { } is not schema-valid

274 | 274 | © 2014 The MITRE Corporation. All rights reserved. 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

275 © 2014 The MITRE Corporation. All rights reserved. | 275 | default

276 | 276 | © 2014 The MITRE Corporation. All rights reserved. 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. { "$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 } default value for "title" See example49

277 | 277 | © 2014 The MITRE Corporation. All rights reserved. " 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"}

278 © 2014 The MITRE Corporation. All rights reserved. | 278 | Expressing co-constraints

279 | 279 | © 2014 The MITRE Corporation. All rights reserved. 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.

280 | 280 | © 2014 The MITRE Corporation. All rights reserved. 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"], "diameter": ["radius"], "length": ["width"], "width": ["length"] }, "additionalProperties": false } If the instance has "radius" then it must also have "diameter" and vice versa. If the instance has “length" then it must also have “width" and vice versa. See example50

281 | 281 | © 2014 The MITRE Corporation. All rights reserved. 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 }

282 | 282 | © 2014 The MITRE Corporation. All rights reserved. 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 }

283 | 283 | © 2014 The MITRE Corporation. All rights reserved. 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".

284 | 284 | © 2014 The MITRE Corporation. All rights reserved. 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 } 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 | 285 | © 2014 The MITRE Corporation. All rights reserved. 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.

286 | 286 | © 2014 The MITRE Corporation. All rights reserved. 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.

287 | 287 | © 2014 The MITRE Corporation. All rights reserved. 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": { "numPassengers": { "type": "integer", "minimum": 1 } }, "required": ["numPassengers"] }, "juicer": { "type": "object", "properties": { "kind": { "type": "string", "enum": ["press", "centrifugal"] } }, "required": [“kind"] } } } If "car" then "numPassengers" If "juicer" then "kind" See example51

288 | 288 | © 2014 The MITRE Corporation. All rights reserved. Schema-valid instance { "car": "Toyota Avalon", "numPassengers": 5 } { "$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"] } } } JSON Schema Validator valid!

289 | 289 | © 2014 The MITRE Corporation. All rights reserved. An instance could also contain "juicer" and its dependent "kind" property { "car": "Toyota Avalon", "numPassengers": 5, "juicer": "Omega Juicer", "kind": "centrifugal" } { "$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"] } } } JSON Schema Validator valid!

290 | 290 | © 2014 The MITRE Corporation. All rights reserved. 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"] } } } Instances can contain no more than 2 properties.

291 © 2014 The MITRE Corporation. All rights reserved. | 291 | Recursion

292 | 292 | © 2014 The MITRE Corporation. All rights reserved. Create a schema for this { "book": { "title": "Title 1", "section": { "title": "Title 1.1", "section": { "title": "Title 1.1.1", "section": { "title": "Title " } } } } } A section contains a title and a section. See the recursion?

293 | 293 | © 2014 The MITRE Corporation. All rights reserved. Here’s what we want title: string section:

294 | 294 | © 2014 The MITRE Corporation. All rights reserved. Create a recursive "definitions" "definitions": { "section": { "type": "object", "properties": { "title": { "type": "string" }, "section": { "$ref": "#/definitions/section" } }, "required": [ "title" ], "additionalProperties": false } },

295 | 295 | © 2014 The MITRE Corporation. All rights reserved. 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" } }

296 | 296 | © 2014 The MITRE Corporation. All rights reserved. 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

297 | 297 | © 2014 The MITRE Corporation. All rights reserved. Unbounded nesting  The recursive schema on the previous slide allows unbounded nesting.  There is no way to limit the amount of nesting or recursion.

298 © 2014 The MITRE Corporation. All rights reserved. The End


Download ppt "© 2014 The MITRE Corporation. All rights reserved. JSON and JSON-Schema for XML Developers Roger L. Costello February 5, 2014 Approved for Public Release;"

Similar presentations


Ads by Google