Copyright © 2016 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and document use rules apply.
The Efficient XML Interchange (EXI) format is a compact representation that simultaneously optimizes performance and the utilization of computational resources. The EXI format was designed to support XML representation. With a relatively small set of transformations it may also be used for JSON, a popular format for exchange of structured data on the Web.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document has been produced by the Efficient XML Interchange Working Group. The goals of the Efficient XML Interchange (EXI) Format are discussed in the Efficient XML Interchange (EXI) Format document. The authors of this document are the members of the Efficient XML Interchange Working Group.
This draft document is intended to be revised and become a Working Group Note.
Publication as a First Public Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. The group does not expect this document to become a W3C Recommendation. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
Please send comments about this document to the public-exi@w3.org mailing list (Archives).
This document is governed by the 1 September 2015 W3C Process Document.
1. Introduction
2. Concept
3. Transforming Data between EXI and JSON
3.1 Transforming from JSON to EXI
3.1.1 JSON object
3.1.2 JSON array
3.1.3 JSON string
3.1.4 JSON number
3.1.5 JSON true
3.1.6 JSON false
3.1.7 JSON null
3.2 Transforming from EXI to JSON
3.2.1 Element j:map
3.2.2 Element j:array
3.2.3 Element j:string
3.2.4 Element j:number
3.2.5 Element j:boolean
3.2.6 Element j:null
3.2.7 Element j:other
A References
B Schema for JSON
C Design Decisions (Non-Normative)
C.1 Selection of other Datatype Representations
C.2 Character Encoding
C.3 Selection of EXI options
C.3.1 EXI Option strict
C.3.2 EXI Option schemaId
D Examples (Non-Normative)
JSON is a popular format for exchange of structured data on the Web and it is specified in [RFC 7159 - The JavaScript Object Notation (JSON) Data Interchange Format] and [ECMA-404 - The JSON Data Interchange Format]. This document describes how the [Efficient XML Interchange (EXI) Format 1.0 (Second Edition)] specification can be used to represent JSON data efficiently in terms of message size and processing.
A number of general mappings between JSON object structures and XML documents have been proposed. Because none of these mappings is ideal in all circumstances, this specification does not attempt to define such a general mapping.
Note:
The goal of this specification has never been to propose a (new) mapping between JSON structures and XML documents. Such a mapping is applicable to EXI already today.
Rather, the EXI for JSON approach is to equivalently convert any well-formed JSON structures to XML event streams (Appendix D Examples shows some examples) that are directly suitable for datatype-aware EXI representation. Lossless round-trip conversion back to the original JSON structures is supported.
The proposed XML event stream results in a compact format - the so-called EXI for JSON document - that can be read and written with little additional software. That said, appendix B Schema for JSON provides an XML Schema describing the EXI for JSON document. EXI processors use the schema-informed grammars that stem from this schema.
The EXI Options describe the EXI options that may be used for any EXI document. Negotiation of what options need to be supported by an EXI for JSON implementation are handled externally to the document. This specification makes use of the default options with the following exceptions:
EXI Option | Description | Value |
---|---|---|
strict | Strict interpretation of schemas is used to achieve better compactness | true |
schemaId | Identify the schema information, if any, used to encode the body | "schema-for-json" |
Both EXI Options for strict and schemaId are REQUIRED and cannot be changed. If future versions of EXI for JSON are specified, version identification is reflected in the schemaId value.
Any valid JSON data can be converted to equivalent EXI. Similarly, corresponding EXI streams that conform to the rules and schema of this specification can be converted to equivalent JSON. This approach is not suitable for arbitrary EXI or XML data.
The following subsections specify how JSON data MUST be transformed to EXI (see 3.1 Transforming from JSON to EXI) and, for equivalent round-trip conversion, how EXI for JSON documents MUST be tranformed to JSON (see 3.2 Transforming from EXI to JSON).
Prefixes are used throughout this section to designate certain namespaces. The bindings shown below are assumed, however, any prefixes can be used in practice if they are properly bound to the namespaces.
Prefix | Namespace Name |
---|---|
j | https://www.w3.org/2015/EXI/json |
Also, the specification makes use of EXI event terminology and the associated grammar notation (e.g., SE stands for Start Element and EE for End Element) that is fully described in the EXI specification dealing with EXI Event Types.
A JSON value is an object
, array
, number
,
or string
, or one of the following three literal names:
true
false
null
.
object
A JSON object
is transformed to a j:map
element.
The entries in the map correspond to the key/value pairs in the JSON object.
The XML event sequence is
SE(j:map) AT(j:key) content EE
if the JSON object is the value of a JSON key/value pair or
SE(j:map) content EE
if this is not the case.
array
A JSON array
is transformed to an j:array
element
whose members are the values of the JSON array.
The XML event sequence is
SE(j:array) AT(j:key) content EE
if the JSON array is the value of a JSON key/value pair or
SE(j:array) content EE
if this is not the case.
string
A JSON string
MAY be transformed to a j:string
element.
The XML event sequence is
SE(j:string) AT(j:key) CH(string-value) EE
if the JSON string is the value of a JSON key/value pair or
SE(j:string) CH(string-value) EE
if this is not the case.
The EXI for JSON transformation rules allow to map a string also to one of the following more optimized XML event sequences
SE(j:other) SE(j:base64Binary) CH(string-value) EE EE
SE(j:other) SE(j:dateTime) CH(string-value) EE EE
SE(j:other) SE(j:time) CH(string-value) EE EE
SE(j:other) SE(j:date) CH(string-value) EE EE
Note:
The above mentioned choice requires that the string-value is representable by the according EXI datatype.
number
A JSON number
MAY be transformed to a j:number
element.
The XML event sequence is
SE(j:number) AT(j:key) CH(number-value) EE
if the JSON number is the value of a JSON key/value pair or
SE(j:number) CH(number-value) EE
if this is not the case.
The EXI for JSON transformation rules allow to map a number also to one of the following more optimized XML event sequences
SE(j:other) SE(j:integer) CH(number-value) EE EE
SE(j:other) SE(j:decimal) CH(number-value) EE EE
Note:
The above mentioned choice requires that the number-value is representable by the according EXI datatype.
Editorial note | |
The working group considers the xsd:decimal support may not be necessary. The benefit and the need of xsd:decimal is unclear. EXI for JSON provides already xsd:double support. Also, requiring additional code for reversing the fractional portion of the Decimal value may not be desired. That said, the working group asks for feedback and use-cases with that regard. |
true
A JSON true
is transformed to a j:boolean
element.
The XML event sequence is
SE(j:boolean) AT(j:key) CH("true") EE
if the JSON true is the value of a JSON key/value pair or
SE(j:boolean) CH("true") EE
if this is not the case.
The EXI for JSON stream has the following information items:
j:map
, j:array
, j:string
,
j:number
, j:boolean
, j:null
, or
j:other
.
j:map
An element j:map
is transformed to
key : { content }
if the element has an attribute key
or
{ content }
if this is not the case.
j:array
An element j:array
is transformed to
key : [ content ]
if the element has an attribute key
or
[ content ]
if this is not the case.
j:string
An element j:string
is transformed to
key : "string-value"
if the element has an attribute key
or
"string-value"
if this is not the case.
j:number
An element j:number
is transformed to
key : number-value
if the element has an attribute key
or
number-value
if this is not the case.
j:boolean
An element j:boolean
is transformed to
key : true
if the element has an attribute key
and the boolean value is
true
or
key : false
if the element has an attribute key
and the boolean value is
false
or
true
if the element does not have an attribute key
and the boolean
value is true
or
false
otherwise.
j:null
An element j:null
is transformed to
key : null
if the element has an attribute key
or
null
if this is not the case.
j:other
An element j:other
is transformed depending on the nested
element.
A nested element j:base64Binary
, j:dateTime
,
j:time
, or j:date
is transformed to
key : "string-value"
if the j:other
element has an attribute key
or
"string-value"
if this is not the case.
A nested element j:integer
or j:decimal
is
transformed to
key : number-value
if the j:other
element has an attribute key
or
number-value
if this is not the case.
The following schema describes the EXI for JSON document (see also schema-for-json.xsd).
<xs:schema xmlns:xs="https://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="https://www.w3.org/2015/EXI/json" xmlns:j="https://www.w3.org/2015/EXI/json"> <!-- * This is a schema for the XML representation of JSON * * The schema is made available under the terms of the W3C software notice and license * at https://www.w3.org/Consortium/Legal/copyright-software-19980720 * --> <xs:element name="map" type="j:mapType"> <xs:unique name="unique-key"> <xs:selector xpath="*"/> <xs:field xpath="@key"/> </xs:unique> </xs:element> <xs:element name="array" type="j:arrayType"/> <xs:element name="string" type="j:stringType"/> <xs:element name="number" type="j:numberType"/> <xs:element name="boolean" type="j:booleanType"/> <xs:element name="null" type="j:nullType"/> <xs:element name="other" type="j:otherType"/> <xs:complexType name="mapType"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="map"> <xs:complexType> <xs:complexContent> <xs:extension base="j:mapType"> <xs:attributeGroup ref="j:key-group"/> </xs:extension> </xs:complexContent> </xs:complexType> <xs:unique name="unique-key-2"> <xs:selector xpath="*"/> <xs:field xpath="@key"/> </xs:unique> </xs:element> <xs:element name="array"> <xs:complexType> <xs:complexContent> <xs:extension base="j:arrayType"> <xs:attributeGroup ref="j:key-group"/> </xs:extension> </xs:complexContent> </xs:complexType> </xs:element> <xs:element name="string"> <xs:complexType> <xs:simpleContent> <xs:extension base="j:stringType"> <xs:attributeGroup ref="j:key-group"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name="number"> <xs:complexType> <xs:simpleContent> <xs:extension base="j:numberType"> <xs:attributeGroup ref="j:key-group"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name="boolean"> <xs:complexType> <xs:simpleContent> <xs:extension base="j:booleanType"> <xs:attributeGroup ref="j:key-group"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name="null"> <xs:complexType> <xs:complexContent> <xs:extension base="j:nullType"> <xs:attributeGroup ref="j:key-group"/> </xs:extension> </xs:complexContent> </xs:complexType> </xs:element> <xs:element name="other"> <xs:complexType> <xs:complexContent> <xs:extension base="j:otherType"> <xs:attributeGroup ref="j:key-group"/> </xs:extension> </xs:complexContent> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> <xs:complexType name="arrayType"> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element ref="j:map"/> <xs:element ref="j:array"/> <xs:element ref="j:string"/> <xs:element ref="j:number"/> <xs:element ref="j:boolean"/> <xs:element ref="j:null"/> <xs:element ref="j:other"/> </xs:choice> </xs:complexType> <xs:simpleType name="stringType"> <xs:restriction base="xs:string"/> </xs:simpleType> <xs:simpleType name="numberType"> <xs:restriction base="xs:double"> <!-- exclude positive and negative infinity, and NaN --> <!-- Note: No real effect for EXI Float datatype --> <xs:minExclusive value="-INF"/> <xs:maxExclusive value="INF"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="booleanType"> <xs:restriction base="xs:boolean"/> </xs:simpleType> <xs:complexType name="nullType"/> <xs:complexType name="otherType"> <xs:choice> <!-- useful types beyond JSON such as binary, date-times, decimal and integer --> <xs:element name="base64Binary"> <xs:simpleType> <xs:restriction base="xs:base64Binary"/> </xs:simpleType> </xs:element> <xs:element name="dateTime"> <xs:simpleType> <xs:restriction base="xs:dateTime"/> </xs:simpleType> </xs:element> <xs:element name="time"> <xs:simpleType> <xs:restriction base="xs:time"/> </xs:simpleType> </xs:element> <xs:element name="date"> <xs:simpleType> <xs:restriction base="xs:date"/> </xs:simpleType> </xs:element> <xs:element name="integer"> <xs:simpleType> <xs:restriction base="xs:integer"/> </xs:simpleType> </xs:element> <xs:element name="decimal"> <xs:simpleType> <xs:restriction base="xs:decimal"/> </xs:simpleType> </xs:element> </xs:choice> </xs:complexType> <xs:attributeGroup name="key-group"> <xs:attribute name="key" type="xs:string"/> </xs:attributeGroup> </xs:schema>
This section discusses a number of key decision points. A rationale for each decision is given and background information is provided.
other
Datatype RepresentationsCompared to the basic JSON datatypes and the according EXI datatype mapping
(i.e., exi:string, exi:double, and
exi:boolean) the element other
allows for other EXI
datatype representations: namely exi:base64Binary, exi:dateTime,
exi:dateTime, exi:time,
exi:date, exi:integer,
and exi:decimal.
The selection of these additional datatypes is based on their foreseen efficiency and potential usage in JSON documents.
JSON text may be encoded in UTF-8, UTF-16, or UTF-32 (see JSON Character Encoding). EXI for JSON matches the JSON specification in that it does not provide an explicit label for the included characters.
If possible without loss of correctness, processors are recommended to use the default UTF-8 for maximum interoperability when creating JSON documents.
EXI for JSON defines a set of predefined EXI Options beyond the default EXI Options.
The default value for strict is false to permit event items not declared in the schemas.
The main reason to set strict to true in the EXI for JSON context is to reduce specification and code complexity while at the same time allowing for simple implementations. In section 3.2 Transforming from EXI to JSON it is specified how to transform an EXI for JSON stream to JSON. Allowing strict to be false would require to deal with unexpected elements and/or attributes and would make the specification more complex while at the same time increase code complexity. The working group concluded that strict being false does not provide any benefit in this context.
Besides that strict being true increases compactness and allows for realizing more optimized processors with less code.
The schemaId is used to identify the schema information used for processing the EXI stream. The value "schema-for-json" has been chosen to identify the schema in appendix B Schema for JSON.
JSON | EXI for JSON | |
---|---|---|
{ "keyNumber": 123, "keyArrayStrings": [ "s1", "s2" ] } | ↔ |
<map xmlns="https://www.w3.org/2015/EXI/json"> <number key="keyNumber">123</number> <array key="keyArrayStrings"> <string>s1</string> <string>s2</string> </array> </map> |
{ "glossary": { "title": "example glossary", "GlossDiv": { "title": "S", "GlossList": { "GlossEntry": { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": { "para": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": [ "GML", "XML" ] }, "GlossSee": "markup" } } } } } | ↔ |
<map xmlns="https://www.w3.org/2015/EXI/json"> <map key="glossary"> <string key="title">example glossary</string> <map key="GlossDiv"> <string key="title">S</string> <map key="GlossList"> <map key="GlossEntry"> <string key="ID">SGML</string> <string key="SortAs">SGML</string> <string key="GlossTerm">Standard Generalized Markup Language</string> <string key="Acronym">SGML</string> <string key="Abbrev">ISO 8879:1986</string> <map key="GlossDef"> <string key="para">A meta-markup language, used to create markup languages such as DocBook. </string> <array key="GlossSeeAlso"> <string>GML</string> <string>XML</string> </array> </map> <string key="GlossSee">markup</string> </map> </map> </map> </map> </map> |