<?xml version="1.0" encoding="utf-8"?>
<?xml-model href="rfc7991bis.rnc"?>
<!DOCTYPE rfc [<!ENTITY nbsp    "&#160;"><!ENTITY zwsp   "&#8203;"><!ENTITY nbhy   "&#8209;"><!ENTITY wj     "&#8288;">]>
<rfc
  xmlns:xi="http://www.w3.org/2001/XInclude"
  category="info"
  docName="draft-thomy-json-ntv-03"
  ipr="trust200902"
  obsoletes=""
  updates=""
  submissionType="IETF"
  xml:lang="en"
  version="2">

  <front>
    <title>JSON semantic format (JSON-NTV)</title>
    <seriesInfo name="Internet-Draft" value="draft-thomy-json-ntv-03"/>
    <author fullname="Philippe THOMY" initials="P." surname="THOMY">
      <organization>Loco-labs</organization>
      <address>
        <postal>
          <street>476 chemin du gaf de Famian</street>
          <city>BOLLENE</city>
          <code>84 500</code>
          <country>FR</country>
        </postal>
        <email>philippe@loco-labs.io</email>
        <uri>https://github.com/loco-philippe/NTV/blob/main/README.md</uri>
      </address>
    </author>
    <date year="2024" month="05" day="27"/>
    <area>General</area>
    <workgroup>Internet Engineering Task Force</workgroup>
    <keyword>JSON</keyword>
    <keyword>semantic</keyword>
    <keyword>data interchange format</keyword>
    <keyword>ABNF</keyword>
    <abstract pn="section-abstract">
      <t>This document describes a set of simple rules for unambiguously and concisely encoding semantic data into
      JSON Data Interchange Format. These rules are based on an NTV (Named and Typed Values) data structure applicable
      to any simple or complex data. </t>
      <t>The JSON-NTV format is its JSON translation.</t>
    </abstract>
  </front>
  &nbsp;
  <middle>
    <section><name>Introduction</name>
      <section><name>Presentation</name>
        <t>The semantic level of JSON or CSV shared data remains low. It is often limited to the type of data defined
        in those exchange formats (strings for CSV formats; numbers, strings, arrays and objects for JSON formats).</t>
        <t>JSON-NTV proposes to increase the semantic level of the JSON entities <xref target="RFC8259"/>
        by adding two additional pieces of information to a JSON entity :<ul>
          <li><strong>name</strong>: interpretation of the JSON value in human language or detailed information or link to external information,</li>
          <li><strong>type</strong>: interpretation of the JSON value in a data standard (eg. GeoJSON, datetime), in a data catalog or
          in a software language.</li></ul></t>
        <t>The NTV entity is thus a triplet with a mandatory element (value) and two additional elements (name, type).</t><ul empty="true">
          <li><em>For example, Paris location can be represented by : </em><ul spacing="compact">
            <li><em>a name : "paris",</em></li>
            <li><em>a type : geoJSON Point coordinates <xref target="RFC7946"/>,</em></li>
            <li><em>a value : [2.3522, 48.8566]</em></li></ul></li></ul>
        <t>The easiest way to add that information into a JSON value is to use a JSON object with a single member.
        The first term is the additional elements using the syntax JSON-ND <xref target="JSON-ND"/>.
        The second term is the JSON value.</t><ul empty="true">
          <li><em>The JSON value of the previous example is:</em><ul spacing="compact" empty="true">
            <li><em>{ "paris:point" : [2.3522, 48.8566] }</em></li></ul></li></ul>
        <t>With this approach, two NTV entities are defined :<ul>
          <li><strong>a primitive entity</strong> which is not composed of any other entity,</li>
          <li><strong>a structured entity</strong> which is an ordered sequence of NTV entities.</li></ul>
        as well as two JSON formats depending on the presence of the additional elements : <ul>
          <li><strong>simple format</strong> when name and type are not present</li>
          <li><strong>named format</strong> when name or type is present </li></ul></t><ul empty="true">
            <li><em>Example (entity composed of two other primitive entities): </em><ul spacing="compact" empty="true">
              <li><em>{ "cities::point": [[2.3522, 48.8566], [4.8357, 45.7640]] }      simple format for primitive entities</em></li>
              <li><em>{"cities::point": {"paris":[2.3522, 48.8566], "lyon":[4.8357, 45.7640]}}      named format for primitive entities</em></li></ul></li></ul>
        <t>A JSON-NTV generator produces a JSON value from a NTV entity and vice versa a JSON-NTV parser transforms a
        JSON value into a NTV entity. </t>
        <t>The document <xref target="NTV-TAB"/> presents a variation of this format for tabular and multidimensional data.</t>
        <t>The conversion between NTV entity and native entity is outside the scope of this note.</t>
      </section>
      <section><name>Key design features</name>
        <t>The format is focused on simplicity, lightness and web usage.</t>
        <t>The key features of this format are the following: <ul>
          <li><strong>JSON as the base format</strong><ul>
            <li>JSON is simple and readable as simple text</li>
            <li>JSON supports rich structure including nesting and basic types</li>
            <li>JSON is web-native and very widely used and supported</li>
            <li>JSON format has binary representation (eg. CBOR format)</li></ul></li>
          <li><strong>high semantic level of data</strong><ul>
            <li>wide variety of data typing</li>
            <li>tree-like and customisable data typing </li></ul></li>
          <li><strong>compatibility with existing formats</strong><ul>
            <li>All JSON data is a JsonNTV data</li>
            <li>All NTVtypes are standard types</li></ul></li>
          <li><strong>compatibility with any type of platform</strong><ul>
            <li>types and structures are independent of software and hardware platforms</li>
            <li>the NTV concept is applicable to all types of "jsonable" data</li></ul></li>
          <li><strong>reversibility</strong><ul>
            <li>the NTV entity coming from a JSON value is identical to the NTV entity from which the JSON value comes</li>
            <li>the JSON representation of an NTV entity is the same as the JSON value used to construct the NTV entity</li></ul></li>
          <li><strong>tree structure</strong><ul>
            <li>all NTV entities are trees</li>
            <li>tree properties are applicable to NTV entities</li></ul></li></ul></t>
      </section>
      <section><name>Conventions Used in This Document</name>
        <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT
          RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 <xref target="RFC2119"/>
          <xref target="RFC8174"/> when, and only when, they appear in all capitals, as shown here.</t>
        <t>This document also uses the following terms:</t><dl newline="true">
          <dt><strong>JsonText, JsonMember, JsonElement :</strong></dt>
          <dd>These terms are defined as text, member, element in the JSON grammar <xref target="RFC8174"/>.</dd>
          <dt><strong>JsonValue, JsonObject, JsonArray, JsonNumber, JsonString, JsonFalse, JsonNull, JsonTrue:</strong></dt>
          <dd>These terms correspond to entities whose representation is defined as value, object, array, number, string, false,
          null, true in the JSON grammar <xref target="RFC8174"/>.</dd>
          <dt><strong>JsonPrimitive:</strong></dt>
          <dd>A JsonNumber, JsonString, JsonFalse, JsonTrue or JsonNull.</dd>
          <dt><strong>JsonUnnamed:</strong></dt>
          <dd>A JsonObject without a single member.</dd>
          <dt><strong>JsonNamed:</strong></dt>
          <dd>A JsonObject with a single member.</dd>
          <dt><strong>NTVsingle, NTVlist:</strong></dt>
          <dd>NTVlist and NTVsingle entities can be abbreviated as:<ul>
                <li>NVsingle : entity with default NTVtype "json",</li>
                <li>NVlist : entity without NTVtype,</li>
                <li>TVsingle, TVlist : entity without NTVname,</li>
                <li>Vsingle, Vlist : NVsingle or NVlist without NTVname.</li></ul></dd></dl>
      </section>
    </section>
    &nbsp;
    <section><name>NTV structure</name>
      <section><name>NTV layers</name>
        <t>NTV and JsonNTV structures are defined as shown in <xref target="NTVlayers-svg" derivedContent="Figure 1"/>:</t><ul>
          <li>NTV is a data triplet (NTVname, NTVtype, NTVvalue) that contains all the information needed to build the native entity. </li>
          <li>JsonNTV is the JsonValue of the NTV entity. JsonNTV is used to build an interchangeable JsonText</li></ul>
        <figure anchor="NTVlayers-svg" align="left" suppress-title="false" pn="figure-1"><name>NTV layers</name><artset>
          <artwork type="svg" name="https://www.rfc-editor.org/materials/format/svg/stream.svg">
            <svg viewBox="0 0 500 100" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
            <!-- Created with SVG-edit - https://github.com/SVG-Edit/svgedit-->
            <g class="layer"><title>Layer 1</title>
              <rect fill="#ffffff" height="35.36" id="svg_1" stroke="#000000" transform="matrix(1 0 0 1 0 0)" width="63.29" x="32.53" y="30"/>
              <text fill="#000000" font-size="10" id="svg_2" stroke="#000000" stroke-width="0" text-anchor="middle" x="66.88" xml:space="preserve" y="50.07">JsonText</text>
              <rect fill="#ffffff" height="35.36" id="svg_4" stroke="#000000" transform="matrix(1 0 0 1 0 0)" width="63.79" x="157.13" y="29.98"/>
              <text fill="#000000" font-size="10" id="svg_3" stroke="#000000" stroke-width="0" text-anchor="middle" transform="matrix(0.98567 0 0 1 0.245089 0)" x="191.49" xml:space="preserve" y="50.05">JsonNTV</text>
              <rect fill="#ffffff" height="35.36" id="svg_8" stroke="#000000" width="63.29" x="401.77" y="30.12"/>
              <text fill="#000000" font-size="10" id="svg_7" stroke="#000000" stroke-width="0" text-anchor="middle" transform="matrix(1 0 0 1 0 0)" x="434.13" xml:space="preserve" y="49.69">native entity</text>
              <path d="m96.43,34.64l59.83,0" fill="#ffffff" id="svg_9" stroke="#000000"/>
              <path d="m146,32.14l-0.22,5.36l10.36,-2.51c-3.38,-0.95 -6.76,-1.9 -10.14,-2.85z" fill="#000000" id="svg_11" stroke="#000000"/>
              <rect fill="#ffffff" height="35.36" id="svg_6" stroke="#000000" transform="matrix(1 0 0 1 0 0)" width="63.79" x="277.27" y="29.9"/>
              <text fill="#000000" font-size="10" id="svg_5" stroke="#000000" stroke-width="0" text-anchor="middle" transform="matrix(1 0 0 1 0 0)" x="311.63" xml:space="preserve" y="49.97">NTV triplet</text>
              <path d="m341.92,35.9l59.5,0" fill="#ffffff" id="svg_12" stroke="#000000"/>
              <path d="m391.16,33.4l-0.22,5.36l10.36,-2.51c-3.38,-0.95 -6.76,-1.9 -10.14,-2.85z" fill="#000000" id="svg_10" stroke="#000000"/>
              <path d="m221.58,35.57l53.83,0" fill="#ffffff" id="svg_14" stroke="#000000"/>
              <path d="m265.16,33.07l-0.22,5.36l10.36,-2.51c-3.38,-0.95 -6.76,-1.9 -10.14,-2.85z" fill="#000000" id="svg_13" stroke="#000000"/>
              <path d="m96.73,57.76l59.83,0" fill="#ffffff" id="svg_17" stroke="#000000"/>
              <path d="m342.22,59.02l59.5,0" fill="#ffffff" id="svg_16" stroke="#000000"/>
              <path d="m221.88,58.69l53.83,0" fill="#ffffff" id="svg_15" stroke="#000000"/>
              <path d="m342.26,56.38l-0.22,5.36l10.36,-2.51c-3.38,-0.95 -6.76,-1.9 -10.14,-2.85z" fill="#000000" id="svg_18" stroke="#000000" transform="rotate(178.552 347.222 59.055)"/>
              <path d="m221.96,55.84l-0.22,5.36l10.36,-2.51c-3.38,-0.95 -6.76,-1.9 -10.14,-2.85z" fill="#000000" id="svg_19" stroke="#000000" transform="matrix(1 0 0 1 0 0) rotate(178.552 226.924 58.5164)"/>
              <path d="m106.62,60.07l0.08,-5.36l-10.29,2.77c3.4,0.86 6.81,1.73 10.21,2.59z" fill="#000000" id="svg_20" stroke="#000000"/>
              <text fill="#000000" font-size="8" id="svg_24" stroke="#000000" stroke-width="0" text-anchor="middle" x="121.5" xml:space="preserve" y="31.72">JSON load</text>
              <text fill="#000000" font-size="8" id="svg_25" stroke="#000000" stroke-width="0" text-anchor="middle" x="127.78" xml:space="preserve" y="66.39">JSON dump</text>
              <text fill="#000000" font-size="8" id="svg_27" stroke="#000000" stroke-width="0" text-anchor="middle" transform="matrix(1 0 0 1 0 0)" x="245.3" xml:space="preserve" y="32.39">NTV load</text>
              <text fill="#000000" font-size="8" id="svg_26" stroke="#000000" stroke-width="0" text-anchor="middle" x="251.58" xml:space="preserve" y="67.05">NTV dump</text>
              <text fill="#000000" font-size="8" id="svg_29" stroke="#000000" stroke-width="0" text-anchor="middle" transform="matrix(1 0 0 1 0 0)" x="368.64" xml:space="preserve" y="33.06">to_obj</text>
              <text fill="#000000" font-size="8" id="svg_28" stroke="#000000" stroke-width="0" text-anchor="middle" x="374.91" xml:space="preserve" y="67.72">from_obj</text>
            </g></svg></artwork>
          <artwork type="ascii-art" name="box.txt">
            <![CDATA[
+--------+ JSON load +-------+ NTV load +-------+  to_obj  +------+
|        |---------->|       |--------->|  NTV  |--------->|native|
|JsonText|           |JsonNTV|          |triplet|          |entity|
|        |<----------|       |<---------|       |<---------|      |
+--------+ JSON dump +-------+ NTV dump +-------+ from_obj +------+
            ]]>
          </artwork></artset></figure>
        <t><em>Example:</em></t><ul>
          <li><em>Native layer</em><ul empty="true">
            <li>new_year_2022 = datetime.date(2022, 01, 01) <em>is a Python variable "new_year_2022" corresponding to a datetime object</em></li></ul></li>
          <li><em>NTV layer</em><ul empty="true">
            <li>("new_year_2022", "date", "2022-01-01") <em>is a triplet</em></li></ul></li>
          <li><em>JsonNTV layer</em><ul empty="true">
            <li>{ "new_year_2022:date" : "2022-01-01" } <em>is a JsonValue</em></li></ul></li>
          <li><em>JsonText layer</em><ul empty="true">
            <li>'{"new_year_2022:date":"2022-01-01"}' <em>is a JsonString</em></li></ul></li></ul>
      </section>
      <section><name>NTV entities</name>
        <t>Two categories of entities (one primitive and one structured) are defined:<ul>
          <li><strong>NTVsingle</strong> for the primitive entity,</li>
          <li><strong>NTVlist</strong> for an ordered sequence of NTV entities</li></ul></t>
        <t>An NTV entity is therefore a tree where the leaves nodes are the NTVsingle entities and where the inner nodes are the NTVlist entities</t>
        <section anchor="NTVsingle"><name>NTVsingle</name>
          <t>The data triplet of NTVsingle entities is composed by:</t><ul>
            <li><strong>NTVsingleValue</strong>: This NTVvalue is the JSON representation (JsonValue) of the main content of the NTV entity,</li>
            <li><strong>NTVsingleType</strong>: This NTVtype is a DataType. It defines the type of entity and the conversion rules between the native entity
            and the NTV entity. The default NTVtype (defaultNTVtype) is the "json" DataType.</li>
            <li><strong>NTVname</strong>: The NTVname is an additional textual information (JsonString)</li></ul>
          <t><strong>In other words, any entity that has on the one hand a function of encoding it into a JsonValue and
          on the other hand a function of creating from a JsonValue can be taken into account.
          This approach is very general because the majority of computer objects are defined by a list of parameters
          (e.g. *args in python) and/or a list of key/values (e.g. **kwargs in python)
          which simply translate into a JsonArray or a JsonObject.</strong></t>
          <t>The consistency between NTVsingleValue and NTVsingleType is outside the scope of this note.</t>
        </section>
        <section><name>NTVlist</name>
          <t>The data triplet of NTVlist entities is composed by:</t><ul>
            <li><strong>NTVlistValue</strong>: This NTVvalue is an ordered sequence of included NTV entities.</li>
            <li><strong>NTVlistType</strong>: This NTVtype is a Namespace or a DataType to apply to the NTV entities included.
            This NTVlistType avoids including a NTVtype (if DataType) or reduces the length (if Namespace) in the JSON representation
            (JsonNTV) of the included NTV entities. The default NTVtype (defaultNTVtype) is "None".</li>
            <li><strong>NTVname</strong>: The NTVname is an additional textual information (JsonString)</li></ul>
          <t><em>Example of equivalent JSON representations:</em></t><ul empty="true">
            <li><em>where NTVlistType is None for the global NTVlist</em><ul empty="true">
              <li><em>[ { ":point" : [2.3522, 48.8566]}, {":point" : [4.8357, 45.7640]} ] </em></li></ul></li>
            <li><em>where NTVlistType is "point" for the global NTVlist</em><ul empty="true">
              <li><em>{ "::point" : [ [2.3522, 48.8566], [4.8357, 45.7640] ] }</em></li></ul></li></ul>
          <t><em>If JsonValue is { "::dat" : ["2022-01-28T18-23-54", {":point": [1.1, 2.2] ] } },
          the parsers deduce that the first NTVvalue has a  "dat" NTVtype and the second a "point" NTVtype.</em></t>
        </section>
      </section>
      <section><name>DataType and Namespace</name>
        <t> A DataType is defined in a nested structure called Namespace.</t>
        <t>This structuring of type makes it possible to reference any type of data that has a JSON representation and to consolidate
        all the shared data structures within the same tree of types.</t>
        <section><name>Namespace</name>
          <t>A Namespace is defined by a name (NamespaceName) and a Namespace parent (NamespaceParent).
          The NamespaceName is unique in the NamespaceParent.</t>
          <t>Root node in the Namespace tree is the GlobalNamespace.</t>
          <ul empty="true"><li><ol type="REQ%d:" group="reqs">
            <li>NamespaceParent of GlobalNamespace is None.</li></ol></li></ul>
        </section>
        <section><name>DataType</name>
          <t>The DataType represents the semantic of a data and is structured in a flat classification. For example, "email" and "string" are two DataType.</t>
          <t>A DataType is composed with a TypeBase and an optional TypeExtension. The TypeExtension defines an additional property. For example:<ul>
            <li>a "float" TypeBase may have a "kg" extension to indicate a unit.</li>
            <li>a "string" TypeBase may have a "fr" extension to indicate a langage. </li></ul></t>
          <t>A DataType is defined by a name (DataTypeName) and a Namespace parent (NamespaceParent).
          The TypeBase of a DataType is unique in the NamespaceParent. The TypeExtension of a DataType is free.</t>
          <t>TypeBase and the rules to encode or decode NTVvalues MUST be understood by data producers and data consumers.
          So TypeBase and rules associated have to be defined in a specification shared by a large community.
          On the other hand, it must be possible for everyone to share data according to their own data structure.</t>
          <t>There are therefore two categories of TypeBase: <ul>
            <li>custom TypeBase (and Namespace) which can be created by anyone without control,</li>
            <li>shared TypeBase (and Namespace) that are defined in a single, shared repository.
            Each 'shared' Namespace or TypeBase is uniquely managed.</li></ul></t>
          <t>For shared TypeBase, three sub-categories are defined (None, Simple, Generic).<ul>
            <li>The "None" TypeBase is used with NTVlist as defaultDataType.</li>
            <li>Simple TypeBase is associated to conversion rules between a native entity and a NTV entity.</li>
            <li>Generic TypeBase is equivalent to a set of Simple TypeBase.
            This indicates that parsers use associated simple TypeBase to decode the JsonNTVvalue.</li></ul></t>
          <t><em>Example:</em> <ul empty="true">
            <li><em>"dat" is the generic TypeBaseName for "datetime" and "timeposix"</em> </li>
            <li><em> If a JSONvalue is { "::dat" : ["2022-01-28T18-23-54", 123456.78] }, the parser deduces that the first entity has a "datetime"
            TypeBaseName and the second a "timeposix" TypeBaseName.</em></li></ul></t>
        </section>
        <section><name>Representation</name>
          <t>A Namespace is defined by a string followed by a point (NamespaceName).</t>
          <t>A DataType is defined by a string (DataTypeName) composed by the TypeBaseName and the TypeExtensionName.</t>
          <t>The representation of a Namespace (NamespaceLongName) is composed by all the nested NamespaceName.</t>
          <t>The representation of a DataType (DataTypeLongName) is composed by the NamespaceLongName and the DataTypeName.</t>
          <t>The DataTypeLongName is defined in  <xref target="DataTypeLongName-abnf" derivedContent="Figure 2"/>,
          which uses ABNF from <xref target="RFC5234"/>.</t>
          <figure anchor="DataTypeLongName-abnf" align="left" suppress-title="false">
            <name>DataType and Namespace names - ABNF</name><sourcecode type="abnf" markers="false">
              <![CDATA[
; representation of DataType and Namespace (Name and LongName)

DataTypeLongName  = NamespaceParentLongName DataTypeName

NamespaceLongName = NamespaceParentLongName NamespaceName
NamespaceParentLongName = NamespaceLongName

NamespaceName   = [ ["$"] JsonString "." ]      ; REQ2 REQ3
DataTypeName    = TypeBaseName ["[" TypeExtensionName "]"]
TypeBaseName    = ["$"] JsonString              ; REQ3
TypeExtensionName   = JsonString
            ]]>
          </sourcecode></figure>
          <t>The corresponding rules are as follows:</t><ul empty="true"><li><ol type="REQ%d:" group="reqs">
            <li>NamespaceName and NamespaceLongName of GlobalNamespace are empty.</li>
            <li>DataType (or Namespace) has 'custom' category if DataTypeName (or NamespaceName) begins with '$' or NamespaceParent has 'custom' category</li></ol></li></ul>
          <t><em>Example for a representation of a DataType defined in two nested Namespace in the global Namespace:</em> <ul empty="true">
            <li><em>"ns1.ns2.type" </em> </li>
            <li><em> where:</em> <ul empty="true">
              <li><em>"ns1." is a NamespaceName of a Namespace defined in the global Namespace,</em> </li>
              <li><em>"ns2." is a NamespaceName of a Namespace defined in the "ns1" Namespace,</em> </li>
              <li><em>"type" is a DataTypeName of a DataType defined in the "ns2" Namespace</em> </li></ul></li></ul></t>
          <t><em>Example of custom categories:</em> <ul empty="true">
            <li><em>If "fr." is the name of a Namespace attached to the global Namespace and containing the Namespace 'BAN' and the DataType 'dep', then:</em> <ul>
              <li><em>"fr.dep" is a name of a shared DataType,</em></li>
              <li><em>"fr.$test" is a name of a custom DataType,</em></li>
              <li><em>"fr.$example.one" is a name of a custom DataType</em></li>
              <li><em>"fr.BAN.$test" is a name of a custom DataType</em></li></ul></li></ul></t>
        </section>
      </section>

    </section>
    &nbsp;
    <section><name>JsonNTV</name>
      <section><name>JsonNTV format</name>
        <t>The JsonNTV format is the JSON representation of an NTV entity (JsonValue). This JsonValue is converted in JsonText with a Json generator.</t>
        <t>The JsonNTV format is defined in <xref target="JsonNTV-abnf" derivedContent="Figure 3"/>, which uses ABNF from <xref target="RFC5234"/>.</t>
        <figure anchor="JsonNTV-abnf" align="left" suppress-title="false">
          <name>JsonNTV - ABNF</name><sourcecode type="abnf" markers="false">
            <![CDATA[
; JSON representation of NTV entities (JsonNTV)

JsonNTV        = JsonNTVnamed / JsonNTVsimple      ; REQ4

JsonNTVnamed   = beginObject JsonNTVMember endObject
JsonNTVsimple  = JsonNTVvalue

JsonNTVMember  = JsonNTVname nSep JsonNTVvalue

; Extract of JSON grammar used in this document

beginArray    = ws "[" ws
beginObject   = ws "{" ws
endArray      = ws "]" ws
endObject     = ws "}" ws
nSep          = ws ":" ws
vSep          = ws "," ws
ws = *( %x20 / %x09 / %x0A / %x0D )

JsonValue  = JsonValue   ; indicates that rule is defined in RFC8259
JsonString = JsonString  ; indicates that rule is defined in RFC8259
            ]]>
        </sourcecode></figure>
        <t>The JsonNTV format is built with the NTVname, NTVvalue and the JsonNTVtype.</t>
        <t>Two JsonNTV formats are defined:<ul>
          <li>named format: <ul empty="true">
            <li><em>{ JsonNTVname : JsonNTVvalue }</em></li></ul></li>
          <li>simple format: <ul empty="true">
            <li><em>JsonNTVvalue</em></li></ul></li></ul></t>
        <t>The corresponding rule is as follows:</t><ul empty="true"><li><ol type="REQ%d:" group="reqs">
          <li>If JsonNTVname is empty, simple format is used else named format is used</li></ol></li></ul>
        <t><em>Note :</em><ul>
          <li><em>JsonNTV : 21, { ":" : 21 } and { ":json" : 21 } represent the same Vsingle entity.</em></li>
          <li><em>If JsonNTVvalue is a JsonObject with a single member, the JsonNTVname is not empty.</em></li></ul></t>
      </section>
      <section><name>JsonNTVname</name>
        <t>JsonNTVname is the concatenation of NTVname and JsonSepType.</t>
        <t>JsonSepType is composed with the separator singleSep or listSep and the JsonNTVtype.</t>
        <t>JsonNTVname and JsonSepType are defined in <xref target="JsonNTVname-abnf" derivedContent="Figure 4"/>,
        which uses ABNF from <xref target="RFC5234"/>.</t>
        <figure anchor="JsonNTVname-abnf" align="left" suppress-title="false">
          <name>JsonNTVname - ABNF</name><sourcecode type="abnf" markers="false">
            <![CDATA[
; JSON representation of NTVname and NTVtype (JsonNTVname)

JsonNTVname = NTVname JsonSepType
JsonSepType = [singleSep [JsonNTVtype]]/([listSep] JsonNTVtype)
    ; REQ5 REQ6

NTVname = JsonString

singleSep   = ":"      ; NTVsingle separator
listSep     = "::"     ; NTVlist separator
          ]]>
        </sourcecode></figure>
        <t>For NTVsingle entities:</t><ul empty="true"><li><ol type="REQ%d:" group="reqs">
          <li><t>If JsonNTVtype is not "json", JsonSepType is identical to singleSep joined with JsonNTVtype,</t>
          <t>else if JsonNTVvalue is not a JsonArray and not a JsonObject, JsonSepType is empty,</t>
          <t>else JsonSepType is identical to singleSep.</t></li></ol></li></ul>
        <t>For NTVlist entities:</t><ul empty="true"><li><ol type="REQ%d:" group="reqs">
          <li><t>If NTVtype is a DataType, listSep is present in JsonSepType</t>
          <t>else listSep is not present.</t></li></ol></li></ul>
      </section>
      <section><name>JsonNTVtype</name>
        <t>The JSON representation of a NTVtype (JsonNTVtype) is a compact representation of the NTVtype in the context of the NTVtypeParent.</t>
        <t>The JsonNTVtype is defined in  <xref target="JsonNTVtype-abnf" derivedContent="Figure 5"/>,
        which uses ABNF from <xref target="RFC5234"/>.</t>
        <figure anchor="JsonNTVtype-abnf" align="left" suppress-title="false" pn="figure-5">
          <name>JsonNTVtype - ABNF</name><sourcecode type="abnf" markers="false">
            <![CDATA[
; JSON representation of NTVType (JsonNTVtype)

JsonNTVtype = [ NTVtypeLongName / NTVtypeRelativeName ]
    ; REQ7

NTVtypeLongName = DataTypeLongName / NamespaceLongName
NTVtypeRelativeName = *NamespaceName (DataTypeName / NamespaceName)
    ; REQ7
            ]]>
        </sourcecode></figure>
        <t>The corresponding rules are as follows:</t><ul empty="true"><li><ol type="REQ%d:" group="reqs">
            <li><t>if NTVtype is identical to NTVtypeParent, JsonNTVtype is empty,</t>
            <t>else if NTVtypeParent is a Namespace and if NTVtype is including in NTVtypeParent,
            JsonNTVtype is the NTVtypeRelativeName (relative to the NTVtypeParent),</t>
            <t>else JsonNTVtype is the NTVtypeLongName</t></li></ol></li></ul>
        <t><em>Example:</em> <ul empty="true">
          <li><em>If "fr." is the name of a Namespace attached to the global Namespace and containing the DataType 'dep', then:</em> <ul>
            <li><em>{ "::fr." : { "department1:dep": "name1", "department2:dep": "name2" } } is a valid JsonNTV representation.</em></li></ul></li></ul></t>
      </section>
      <section><name>JsonNTVvalue</name>
        <t>The JsonNTVvalue is the JsonValue representation of NTVvalue as defined in <xref target="JsonNTVvalue-abnf" derivedContent="Figure 6"/>,
        which uses ABNF from <xref target="RFC5234"/>.</t>
        <figure anchor="JsonNTVvalue-abnf" align="left" suppress-title="false" pn="figure-6">
          <name>JsonNTVvalue - ABNF</name><sourcecode type="abnf" markers="false">
            <![CDATA[
; JSON representation of NTVvalue (JsonNTVvalue)

JsonNTVvalue       = JsonNTVsingleValue / JsonNTVlistValue

JsonNTVsingleValue = NTVsingleValue
JsonNTVlistValue   = JsonNTVarrayValue / JsonNTVobjectValue
    ; REQ8 REQ9

JsonNTVarrayValue  = beginArray ListJsonNTVvalue endArray
ListJsonNTVvalue   = [JsonNTV  *( vSep JsonNTV )]
JsonNTVobjectValue = beginObject ListJsonNTVmember endObject
ListJsonNTVmember  = [JsonNTVMember *( vSep JsonNTVMember)]

NTVsingleValue     = JsonValue
            ]]>
        </sourcecode></figure>
        <t>For a NTVsingle, JsonNTVvalue is the NTVvalue.</t>
        <t>For a NTVlist, JsonNTValue has two representations:<ul>
          <li>a JsonArray where JsonElements are the JsonNTV of included NTV entities,</li>
          <li>a JsonObject where the JsonMembers are the JsonMembers of the JsonNTV of included NTV entities.</li></ul></t>
        <t>The corresponding rules are as follows:</t><ul empty="true"><li><ol type="REQ%d:" group="reqs">
          <li>NTVlist with multiple NTV entities : if all JsonNTVname of NTV entities are different and not empty,
          JsonNTVobjectValue is used else JsonNTVarrayValue is used</li>
          <li>NTVlist with single NTV entity : if JsonNTVname of the NTVlist is not empty JsonNTVobjectValue is used
          else JsonNTVarrayValue is used</li></ol></li></ul>
        <t><em>Example:</em><ul empty="true">
          <li><em>{ ":point" : [2.3522, 48.8566], ":point" : [4.8357, 45.7640] }   is not a valid JsonNTV</em></li></ul></t>
      </section>
    </section>
    &nbsp;
    <section><name>Examples</name>
      <t>Examples of JsonNTV representation of NTV entities:</t>
      <t><strong>Vsingle :</strong></t><ul empty="true">
        <li><em>"lyon"</em></li>
        <li><em>52.5</em></li>
        <li><em>{ ":" : [4.8357, 45.7640] }</em></li></ul>
      <t><strong>NVsingle : </strong></t><ul empty="true">
        <li><em>{ "city" : "paris" }</em></li>
        <li><em>{ "paris:" : [4.8357, 45.7640] }</em></li></ul>
      <t><strong>TVsingle: </strong></t><ul empty="true">
        <li><em>{ ":point" : [4.8357, 45.7640] }</em></li>
        <li><em>{ ":string[fr]" : "Paris est un belle ville" }</em></li></ul>
      <t><strong>NTVsingle: </strong></t><ul empty="true">
        <li><em>{ "paris:point" : [2.3522, 48.8566] }</em></li>
        <li><em>{ "paris:ntv" : { "coordinate:point" : [4.8357, 45.7640] } }</em></li></ul>
      <t><strong>Vlist (composed with JsonArray): </strong></t><ul empty="true">
        <li><em>[4, 45]</em></li>
        <li><em>["paris"]</em></li>
        <li><em>[ [2.3522, 48.8566], {"lyon" : [4.8357, 45.7640]} ]</em></li>
        <li><em>[ { ":point" : [2.3522, 48.8566]}, {":point" : [4.8357, 45.7640]} ]</em></li>
        <li><em>[]</em></li></ul>
      <t><strong>Vlist (composed with JsonObject) :</strong></t><ul empty="true">
        <li><em>{ "name": "white", "firstname":"walter", "surname":"heisenberg" }</em></li>
        <li><em>{ "paris:point" : [2.3522, 48.8566] , "lyon" : "france"}</em></li>
        <li><em>{ "paris" : [2.3522, 48.8566], "" : [4.8357, 45.7640]}</em></li>
        <li><em>{ }</em></li></ul>
      <t><strong>NVlist : </strong></t><ul empty="true">
        <li><em>{ "simple list": [4, 45.7]}</em></li>
        <li><em>{ "cities": [{":point": [2.3522, 48.8566]}, {":point": [4.8357, 45.7640]}]}</em></li></ul>
      <t><strong>TVlist : </strong></t><ul empty="true">
        <li><em>{ "::point": [[2.3522, 48.8566], {"lyon" : [4.8357, 45.7640]} ] }</em></li>
        <li><em>{ "::dat": [ "2022-01-28T18-23-54Z", "2022-01-28", 1234.78 ] }</em></li></ul>
      <t><strong>NTVlist : </strong></t><ul empty="true">
        <li><em>{ "cities::point": [[2.3522, 48.8566], {"lyon": [4.8357, 45.7640]}] }</em></li>
        <li><em>{ "generic date::dat": [ "2022-01-28T18-23-54Z", "2022-01-28", 1234.78]}</em></li>
        <li><em>{ "various::point": [ [2.3, 48.8], { ":date": "2022-01-28"}, {":json": 25 }, { "another NTVlist::json": [1,2,3]} ]}</em></li></ul>
      <t><strong>NTVlist and NVlist (composed with JsonObject) :</strong></t><ul empty="true">
        <li><em>{ "cities::point": { "paris": [2.352, 48.856], "lyon": [4.835, 45.764]}}</em></li>
        <li><em>{ "cities": {"paris:point": [2.3522, 48.8566] , "lyon": "france"}}</em></li></ul>
    </section>
    &nbsp;
    <section><name>Parsing a JsonValue</name>
      <t>JsonValue is parsed according to JSON structure (from root to leaves).</t>
      <t>Several steps are considered:</t><ul>
        <li>JSON decoding</li>
        <li>NTV entity decoding</li>
        <li>NTVvalue decoding</li>
        <li>NTVtype decoding</li></ul>
      <section><name>JSON decoding</name>
        <t>This part is not detailed and consists of:</t><ul>
            <li>exploit the JSON structure to identify JsonNTVname and JsonNTVvalue,</li>
            <li>extract the following data from the JsonNTVname string: JsonNTVtype, NTVname and singleSep or listSep</li></ul>
      </section>
      <section><name>NTV entity decoding</name>
        <t>The NTV entity is inferred from the JSON structure of JsonValue or JsonNTVvalue:</t><ul empty="true"><li><ol type="PARS%d:" group="parsing reqs">
            <li>The tables <xref target="table1"/> and <xref target="table2"/> define the entity identification rules (NTVsingle or NTVlist)</li></ol></li></ul>
        <table anchor="table1" align="left" pn="table-1"><name>Decoding JsonValue</name><thead>
          <tr><th>JsonValue</th><th>NTV entity</th></tr></thead><tbody>
          <tr><td>JsonPrimitive</td><td>Vsingle</td></tr>
          <tr><td>JsonUnnamed</td><td>Vlist</td></tr>
          <tr><td>JsonArray</td><td>Vlist</td></tr>
          <tr><td>JsonNamed</td><td>see <xref target="table2"/></td></tr></tbody></table>
        <table anchor="table2" align="left" pn="table-2"><name>Decoding JsonNTVvalue</name><thead>
          <tr><th>Separator</th><th>JsonNTVvalue</th><th>NTV entity</th></tr></thead><tbody>
          <tr><td>None</td><td>JsonPrimitive</td><td>NVsingle</td></tr>
          <tr><td>None</td><td>JsonNamed</td><td>NVsingle</td></tr>
          <tr><td>None</td><td>JsonUnnamed</td><td>NVlist</td></tr>
          <tr><td>None</td><td>JsonArray</td><td>NVlist</td></tr>
          <tr><td>":"</td><td>JsonValue</td><td>TVsingle or NTVSingle</td></tr>
          <tr><td>"::"</td><td>JsonUnnamed</td><td>NVlist or TVlist or NTVlist</td></tr>
          <tr><td>"::"</td><td>JsonArray</td><td>NVlist or TVlist or NTVlist</td></tr></tbody></table>
      </section>
      <section><name>NTVvalue decoding</name>
        <t>The NTVvalue is inferred from the JsonNTVvalue:</t><ul empty="true"><li><ol type="PARS%d:" group="parsing reqs">
            <li>The NTVvalue of NTVsingle is the JsonNTVvalue.</li>
            <li>The NTVvalue of NTVlist is the list of NTV entities parsed for each JsonElement or JsonMember including in the JsonNTVvalue.</li></ol></li></ul>
      </section>
      <section><name>NTVtype decoding</name>
        <t>NTVtype is inferred from the JsonNTVtype:</t><ul empty="true"><li><ol type="PARS%d:" group="parsing reqs">
            <li><t>If JsonNTVtype is a valid NTVtypeLongName : NTVtype is the decoded JsonNTVtype,</t>
            <t>else if concatened ParentNTVtypeLongName with JsonNTVtype is empty : NTVtype is "json",</t>
            <t>else if the decoded of concatenation of ParentNTVtypeLongName with JsonNTVtype is a valid  NTVtypeLongName : NTVtype is it,</t>
            <t>else NTVtype is the defaultNTVtype</t></li></ol></li></ul>
        <t>The <xref target="JSON-NTV"/> repository gives some examples of NTV usage.</t>
      </section>
    </section>
    &nbsp;
    <section><name>Properties</name>
      <section><name>NTV tree</name>
        <t>An NTV entity is a tree where the leaf nodes are the NTVsingle entities and where the inner nodes are the NTVlist entities.</t>
        <t>Therefore the tree property are applicable:</t><ul>
          <li>tree indicators can be calculate:<ul>
            <li>breadth : number of NTVsingle entities (leaves)</li>
            <li>size : number of NTV entities (nodes)</li>
            <li>height :  length of the longest downward path to a leaf</li></ul></li>
          <li>An ordering list of nodes can be defined to explore the tree for example according to the DFS pre-ordering algorithm<xref target="DFS"/>
          (this order is the same as the order in a JsonValue ),</li></ul>
      </section>
      <section><name>NTV Pointer</name>
        <t>A NTV Pointer is a string syntax for identifying a specific NTV entity within a NTV tree.</t>
        <t>The syntax defined for JSON Pointer <xref target="RFC6901"/> (json-pointer, reference-token)
        is transposable to NTV Pointer (ntv-pointer, reference-token):</t><ul>
          <li>The ntv-pointer is a Unicode string containing a sequence of zero or more reference-tokens, each prefixed by a '/'.</li>
          <li>The reference-token is the NTVname if it exists otherwise the zero-based index of the NTV entity in the NTVvalue list.</li></ul>
        <t>The ntv-pointer is equal to the json-pointer of the JsonNTV representation in most cases except :</t><ul>
          <li>if the JsonNTV is a JsonObject with a single member where the value is a JsonPrimitive,</li>
          <li>- if the JsonNTV contains a JsonArray containing a JsonObject with a single member where the value is a JsonPrimitive</li></ul>
      </section>
      <section><name>NTV Comparison</name>
        <t>Three levels of equality are defined.</t>
        <t><strong>Strict equality:</strong></t><ul empty="true">
          <li>Two NTV entities are strictly equals if : <ul>
            <li>the NTVname are identical</li>
            <li>the NTVtypes are identical</li>
            <li>the NTVvalue are identical<ul>
              <li>if the NTVvalue is a list of NTV entities, each NTV entity has to be identical</li>
              <li>if the NTVvalue is a JSONvalue, the JSONvalues have to be identical</li></ul></li></ul></li></ul>
        <t><strong>Structural equality:</strong></t><ul empty="true">
          <li>Two NTV entities are structurally equals if :<ul>
            <li>the NTVname are identical</li>
            <li>the NTVtypes of NTVsingle are identical</li>
            <li>the NTVvalue are structurally identical:<ul>
              <li>if the NTVvalue is a list of NTV entities, each NTV entity has to be structurally identical</li>
              <li>if the NTVvalue is a JSONvalue, the JSONvalues have to be identical</li></ul></li></ul></li>
          <li><em>Example of structural equality (JsonNTV representation):</em><ul empty="true">
            <li><em> {"::int32": [10, 20] }   and   [{":int32": 10}, {":int32": 20}]</em></li></ul></li></ul>
        <t><strong>Semantic equality:</strong></t><ul empty="true">
          <li>Two NTV entities are semantically equals if :<ul>
            <li>the NTVname are identical</li>
            <li>the NTVvalue are semantically identical:<ul>
              <li>if the NTVvalue is a list of NTV entities, each NTV entity has to be semantically identical</li>
              <li>if the NTVvalue is a JSONvalue, the native entity associated to the JSONvalue have to be identical</li></ul></li></ul></li>
          <li><em>Example of semantic equality (JsonNTV representation):</em><ul empty="true">
            <li><em> {":datetime": "2011-11-04T10:05:23+00:00" } and {":datetime": "2011-11-04T11:05:23+01:00"}</em></li></ul></li></ul>
      </section>
      <section><name>NTV Canonical</name>
        <t>The NTVtype of the NTVlist entities is only useful for constructing the JSON representation (two NTVlists with two different NTVtypes are equal
        according to the structural equality criteria).</t>
        <t>A canonical (single) format is chosen to facilitate sharing and analysis of NTV and JsonNTV data. It is defined by setting a value
        for the NTVtype of an NTVlist entity.</t>
        <t>The rule is as follows:</t><ul empty="true"><li><ol type="REQ%d:" group="reqs">
          <li><t>NTVtype is empty, if an included entity is an NTVlist with an empty NTVtype,</t>
          <t>NTVtype is empty, if all included entities have an NTVtype 'json',</t>
          <t>NTVtype is the common Namespace, if the common Namespace is not the GlobalNamespace,</t>
          <t>In other cases, the NTVtype is the same as that of the first included entity.</t></li></ol></li></ul>
        <t>This rule is simple to implement and allows you to have a compact JsonNTV format (another more complex choice would have been to take
          the most frequent NTVtype among the included entities).</t>
      </section>
      <section><name>JSON as a subtype of NTV</name>
        <t>The <xref target="JsonNTV format"/> shows that there is an equivalence between Json entities (JsonArray, JsonObject, JsonNumber, JsonString, JsonFalse, JsonTrue or JsonNull)
         and the corresponding NTV entities called JNTV (resp. NTVarray, NTVobject, NTVnumber, NTVstring, NTVfalse, NTVtrue , NTVnull).</t>
        <t>JNTV entities have several properties:</t><ul>
          <li>JNTV and JSON structures are substitutable with respect to functions associated with Json structures (e.g. generation of the JsonText format),</li>
          <li>Strict equality or Structural equality between two JNTV entities are equivalent to equality between JsonNTV representations</li>
          <li>JNTV are canonical NTV entity</li>
          <li>NTV Pointer of JNTV are identical to Json Pointer of JsonNTV representations</li></ul>
      </section>
      <section><name>extended NTV structure</name>
        <t>The NTVvalue of NTV entities are JsonValue. In the extended NTV structure, NTVvalue can be every kind of data.</t>
        <t>With this structure, the NTV representation is a "json like" data where:</t><ul>
          <li>JsonNTVvalue is always NTVvalue,</li>
          <li>JsonNTVtype is optional (if NTVtype can be deduced from the NTVvalue),</li>
          <li>JsonNTVname is optional (if NTVname can be deduced from the NTVvalue).</li></ul>
        <t><em>Examples of extended NTV representation:</em></t><ul empty="true">
          <li><ul empty="true"><li><t><em>{ "python date" : [ datetime.date(2022, 1, 18), datetime.date(2023, 1, 12) ] }</em></t></li></ul></li>
          <li><em>this "json like" structure can be converted in JsonNTV format:</em></li>
          <li><ul empty="true"><li><t><em>{ "python date::date" : [ "2022-01-18", "2023-01-12" ] }</em></t></li></ul></li></ul>
      </section>
      <section><name>nested NTVsingle entities</name>
        <t>As defined in <xref target="NTVsingle"/> an entity with Json representation can be taken into account.</t>
        <t><xref target="global"/> defines usual NTVtypes (e.g. date, coordinate, email) but also NTVtypes associated to structured data
        (e.g. dataset, NTV data, custom format):</t>
        <t>The example in <xref target="nested NTVsingle"/> is the representation of a NTVlist with three NTVsingle:</t><ul>
          <li>"dataset" is a NTVsingle build with a 'tab' structure (NTVdataset defined in <xref target="NTV-TAB"/>). This NTVdataset includes in 'field2' an NTV structure,</li>
          <li>"ntvdata" is a NTVsingle build with a 'ntv' structure. This structure includes an other NTV structure,</li>
          <li>"sensor" is a NTVsingle build with a custom structure. This structure includes a NTVdataset.</li></ul>
        <figure anchor="nested NTVsingle" align="left" suppress-title="false" pn="figure-7">
          <name>Nested NTVsingle</name><sourcecode><![CDATA[
ex_list = {
  "structure": {
    "dataset:tab":{
      "field1": [1,2,3],
      "field2": [4,5,{":ntv": {"min": 6, "max": 7}]
    },
    "ntvdata:ntv":{
      "equinox:date": "2024-03-20",
      "paris:point": [2.35, 48.85],
      "other data:ntv": {"val1": 1, "val2": 2}
    },
    "sensor:$sensor": [
      8.51, 3.5, 4.2,
      {":tab": [[1,2,3,4], [5,6,7,8]]}
    ]
  }
}
        ]]></sourcecode></figure>
        <t>Nested NTVsingle is treated as simple NTVsingle and can be used with extended NTV structures.</t>
      </section>
    </section>
    &nbsp;
    <section anchor="IANA"><name>IANA Considerations</name>
      <t>No IANA actions are required :</t><ul empty="true">
        <li>Any JsonValue is a JsonNTVValue and conversely, any JsonNTVvalue is a JsonValue.</li>
        <li>Thus, any JSON data may or may not be treated as JsonNTV data, so there is no need to create a specific MIME media type for JsonNTV.</li>
        <li>All properties of the MIME media type "application/json" are applicable.</li></ul>
    </section>
    <section anchor="Security"><name>Security Considerations</name>
      <t>The format used for NTV data exchanges is the JSON format.
      So, all the security considerations of <xref target="RFC8259"/> apply.</t>
      <t>The NTV structure provides no cryptographic integrity protection of any kind.</t>
    </section>
  </middle>
  &nbsp;
  <back>
    <references><name>References</name>
      <references><name>Normative References</name>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4648.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7946.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5234.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6901.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8259.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3339.xml"/>
        <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7950.xml"/>
      </references>
      <references><name>Informative References</name>
        <reference anchor="DFS" target="https://en.wikipedia.org/wiki/Depth-first_search"><front>
          <title>Depth-first search algorithm</title><author><organization>"Wikipedia"</organization></author></front></reference>
        <reference anchor="NTV-TAB" target="https://datatracker.ietf.org/doc/draft-thomy-ntv-tab/"><front>
          <title>NTV tabular format (NTV-TAB)</title><author initials="P" surname="Thomy"></author><date year="2023"/></front></reference>
        <reference anchor="JSON-ND" target="https://github.com/glenkleidon/JSON-ND"><front>
          <title>JSON-ND</title><author initials="G" surname="Kleidon"></author><date year="2020"/></front></reference>
        <reference anchor="JSON-NTV" target="https://github.com/loco-philippe/NTV#readme"><front>
          <title>JSON-NTV</title><author initials="P" surname="Thomy"></author><date year="2022"/></front></reference>
        <reference anchor="OLC" target="https://github.com/google/open-location-code"><front>
          <title>Open Location Code</title><author><organization>"Google"</organization></author><date year="2016"/></front></reference>
        <reference anchor="W3C TAB" target="https://www.w3.org/TR/2015/REC-tabular-data-model-20151217/"><front>
          <title>Recommendation : Model for Tabular Data and Metadata on the Web</title>
          <author><organization>"W3C"</organization></author><date year="17 December 2015"/></front></reference>
        <reference anchor="ISO 3166-1 alpha-2" target="https://www.iso.org/standard/72482.html"><front>
          <title>Codes for the representation of names of countries and their subdivisions - Part 1: Country code</title>
          <author><organization>"ISO"</organization></author><date year="2020"/></front></reference>
        <reference anchor="TABLE SCHEMA" target="https://specs.frictionlessdata.io/table-schema/#types-and-formats"><front>
          <title>Table Schema specification</title>
          <author><organization>"Frictionless"</organization></author><date year="5 October 2021"/></front></reference>
        <reference anchor="JSON SCHEMA" target="https://json-schema.org/draft/2020-12/json-schema-validation"><front>
          <title>JSON Schema validation</title>
          <author><organization>"JSON Schema"</organization></author><date year="16 June 2022"/></front></reference>
      </references>
    </references>
    &nbsp;
    <section anchor="global"><name>Global DataType and Namespace</name>
      <t>The structure of DataType by Namespace makes it possible to have DataType or Namespace corresponding to recognized standards at the global level.</t>
      <t>A standard DataType / Namespace is a DataType / Namespace defined in the Global Namespace.</t>
      <t>The standard DataType and Namespace are listed below.</t>
      <section><name>Json</name>
        <t>Json DataType have a generic DataType : "json"</t>
        <table anchor="table3" align="left" pn="table-3"><name>Json DataType</name><thead>
          <tr><th>DataTypeName (generic)</th><th>NTVvalue</th><th>example NTVvalue</th></tr></thead><tbody>
          <tr><td>json</td><td>generic DataType</td><td></td></tr>
          <tr><td>number (json)</td><td>JsonNumber <xref target="RFC8259"/></td><td>10</td></tr>
          <tr><td>boolean (json)</td><td>JsonBoolean <xref target="RFC8259"/></td><td>"true"</td></tr>
          <tr><td>null (json)</td><td>JsonNull <xref target="RFC8259"/></td><td>"null"</td></tr>
          <tr><td>string (json)</td><td>JsonString <xref target="RFC8259"/></td><td>"value"</td></tr>
          <tr><td>array (json)</td><td>JsonArray <xref target="RFC8259"/></td><td>[1.1, 2.2]</td></tr>
          <tr><td>object (json)</td><td>JsonObject <xref target="RFC8259"/></td><td>{"value1": 1, "value2": 2}</td></tr></tbody></table>
      </section>
      <section><name>Numbers</name>
        <table anchor="table4" align="left" pn="table-4"><name>Numbers DataType</name><thead>
          <tr><th>DataTypeName</th><th>NTVvalue</th><th>comment</th></tr></thead><tbody>
          <tr><td>int</td><td>JsonNumber <xref target="RFC8259"/></td><td>integer</td></tr>
          <tr><td>int8, int16, int32, int64</td><td>JsonNumber <xref target="RFC8259"/></td><td>signed integer</td></tr>
          <tr><td>uint8, uint16, uint32, uint64</td><td>JsonNumber <xref target="RFC8259"/></td><td>unsigned integer</td></tr>
          <tr><td>decimal64</td><td>JsonNumber <xref target="RFC8259"/></td><td>decimal floating point</td></tr>
          <tr><td>float</td><td>JsonNumber <xref target="RFC8259"/></td><td>binary floating point</td></tr>
          <tr><td>float16, float32, float64</td><td>JsonNumber <xref target="RFC8259"/></td><td>binary floating point</td></tr></tbody></table>
      </section>
      <section><name>Binary encoding</name>
        <table anchor="table5" align="left" pn="table-5"><name>Binary DataType</name><thead>
          <tr><th>DataTypeName</th><th>NTVvalue</th><th>comment</th></tr></thead><tbody>
          <tr><td>bit</td><td>binary digit</td><td>string "0" or "1"</td></tr>
          <tr><td>binary</td><td>bit string</td><td>string of bit array</td></tr>
          <tr><td>base16</td><td>base16 encoding <xref target="RFC4648"/></td><td>string of hexadecimal array</td></tr>
          <tr><td>base32</td><td>base32 encoding <xref target="RFC4648"/></td><td>string of duotrigesimal array</td></tr>
          <tr><td>base64</td><td>base64 encoding <xref target="RFC4648"/></td><td>string of tetrasexagesimal array</td></tr></tbody></table>
      </section>
      <section><name>Datation</name>
        <t>Datation DataType have a generic DataType : "dat"</t>
        <table anchor="table6" align="left" pn="table-6"><name>Datation DataType</name><thead>
          <tr><th>DataTypeName (generic)</th><th>NTVvalue</th><th>example NTVvalue</th></tr></thead><tbody>
          <tr><td>year</td><td>fullyear <xref target="RFC3339"/></td><td>1998</td></tr>
          <tr><td>month</td><td>month <xref target="RFC3339"/></td><td>10</td></tr>
          <tr><td>yearmonth</td><td>year + month (ISO8601-1)</td><td>1998-10</td></tr>
          <tr><td>day</td><td>mday <xref target="RFC3339"/> day of month</td><td>21</td></tr>
          <tr><td>wday</td><td>wday <xref target="RFC3339"/> day of week</td><td>7</td></tr>
          <tr><td>yday</td><td>yday <xref target="RFC3339"/> day of year</td><td>360</td></tr>
          <tr><td>week</td><td>week <xref target="RFC3339"/></td><td>38</td></tr>
          <tr><td>hour</td><td>hour <xref target="RFC3339"/></td><td>20</td></tr>
          <tr><td>minute</td><td>minute <xref target="RFC3339"/></td><td>18</td></tr>
          <tr><td>second</td><td>second <xref target="RFC3339"/></td><td>54</td></tr>
          <tr><td>dat</td><td>generic DataType</td><td> </td></tr>
          <tr><td>date (dat)</td><td>date <xref target="RFC3339"/></td><td>"2022-01-28""</td></tr>
          <tr><td>time (dat)</td><td>timespec-base [time-fraction]<xref target="RFC3339"/></td><td>"T18:23:54",  "18:23", "T18"</td></tr>
          <tr><td>timetz (dat)</td><td>timespec-base [time-fraction] time-zone<xref target="RFC3339"/></td><td>"T18:23:54+0400"</td></tr>
          <tr><td>datetime (dat)</td><td>iso-date-time (without time-zone)<xref target="RFC3339"/></td><td>"2022-01-28T18-23-54"</td></tr>
          <tr><td>datetimetz (dat)</td><td>iso-date-time (with time-zone)<xref target="RFC3339"/></td>
            <td>"2022-01-28T18-23-54+0400"</td></tr></tbody></table>
      </section>
      <section><name>Period and Duration</name>
        <table anchor="table7" align="left" pn="table-7"><name>Period and Duration DataType</name><thead>
          <tr><th>DataTypeName</th><th>NTVvalue</th><th>example NTVvalue</th></tr></thead><tbody>
          <tr><td>duration</td><td>duration <xref target="RFC3339"/></td><td>"P3Y6M4DT12H30M5S"</td></tr>
          <tr><td>timearray</td><td>JsonArray</td><td><t>[dat1, dat2]</t><t><em>dat1, dat2 have "dat" DataTypeName</em></t></td></tr>
          <tr><td>period</td><td>period <xref target="RFC3339"/></td>
            <td><t>"2022-01-01 / 2022-01-30"</t><t>"2022-01-01 / P3Y6M4DT12H30M5S"</t></td></tr></tbody></table>
      </section>
      <section><name>Location</name>
        <t>Location DataType have a generic DataType : "loc".</t>
        <t>The CRS (Coordinate Reference Systems) is geographic, using the World Geodetic System 1984 (WGS 84) datum,
        with longitude and latitude units of decimal degrees (EPSG:4326).</t>
        <table anchor="table8" align="left" pn="table-8"><name>Location DataType</name><thead>
          <tr><th>DataTypeName (generic)</th><th>NTVvalue</th><th>example NTVvalue</th></tr></thead><tbody>
          <tr><td>loc</td><td>generic DataType</td><td></td></tr>
          <tr><td>point (loc)</td><td>Point coordinates <xref target="RFC7946"/></td><td>[ 5.12, 45.256 ] <em>(lon, lat)</em></td></tr>
          <tr><td>pointstr (loc)</td><td>Point coordinates (string)</td><td>"5.12, 45.256" <em>(lon, lat)</em></td></tr>
          <tr><td>pointobj (loc)</td><td>Point coordinates (object)</td><td>{"lon": 5.12, "lat": 45.256}</td></tr>
          <tr><td>multipoint</td><td>MultiPoint coordinates <xref target="RFC7946"/></td>
            <td><t>[pt1, pt2, pt3]</t><t><em>ptx is "point" NTVvalue</em></t></td></tr>
          <tr><td>line (loc)</td><td>LineString coordinates <xref target="RFC7946"/></td>
            <td><t>[pt1, pt2, pt3]</t><t><em>ptx is "point" NTVvalue</em></t></td></tr>
          <tr><td>multiline</td><td>MultiLineString coordinates <xref target="RFC7946"/></td>
            <td><t>[li1, li2, li3]</t><t><em>lix is "line" NTVvalue</em></t></td></tr>
          <tr><td>polygon (loc)</td><td>Polygon coordinates <xref target="RFC7946"/></td>
            <td><t>[rg1, rg2, rg3]</t><t><em>rgx is "line" NTVvalue (ring)</em></t></td></tr>
          <tr><td>multipolygon (loc)</td><td>MultiPolygon coordinates <xref target="RFC7946"/></td>
            <td><t>[pl1, pl2, pl3]</t><t><em>plx is "polygon" NTVvalue</em></t></td></tr>
          <tr><td>geometry</td><td>Geometry coordinates <xref target="RFC7946"/></td>
            <td><t>"point", "line" or "polygon"</t><t>NTVvalue</t></td></tr>
          <tr><td>multigeometry</td><td>MultiGeometry coordinates <xref target="RFC7946"/></td>
            <td><t>[geo1, geo2, geo3]</t><t><em>geox is "geometry" NTVvalue</em></t></td></tr>
          <tr><td>box (loc)</td><td>box coordinates <xref target="RFC7946"/></td><td>[ -10.0, -10.0, 10.0, 10.0 ]</td></tr>
          <tr><td>geojson (loc)</td><td>geoJSON object <xref target="RFC7946"/></td><td>{"type": "point", "coordinates": [40.0, 0.0]}</td></tr>
          <tr><td>codeolc (loc)</td><td>Open Location Code <xref target="OLC"/></td><td>"8FW4V75V+8F6"</td></tr></tbody></table>
      </section>
      <section><name>Structured data</name>
        <table anchor="table9" align="left" pn="table-9"><name>Structured DataType</name><thead>
          <tr><th>DataTypeName</th><th>NTVvalue</th></tr></thead><tbody>
          <tr><td>row</td><td>row <xref target="W3C TAB"/></td></tr>
          <tr><td>field</td><td>column <xref target="W3C TAB"/></td></tr>
          <tr><td>tab</td><td>table <xref target="NTV-TAB"/></td></tr>
          <tr><td>ndarray</td><td>multidimensional array <xref target="NTV-TAB"/></td></tr>
          <tr><td>xndarray</td><td>labelled multidimensional array<xref target="NTV-TAB"/></td></tr>
          <tr><td>xdataset</td><td>coordinated multidimensional array<xref target="NTV-TAB"/></td></tr>
          <tr><td>ntv</td><td>JsonNTV</td></tr>
          <tr><td>sch</td><td>Schema</td></tr></tbody></table>
          <t>The data structure associated to this DataTypeName are defined in specific document.</t>
      </section>
      <section><name>Normalized String</name>
        <table anchor="table10" align="left" pn="table-10"><name>Structured DataType</name><thead>
          <tr><th>DataTypeName</th><th>NTVvalue</th><th>example NTVvalue</th></tr></thead><tbody>
          <tr><td>unit</td><td>Physical quantities</td><td>"kg / s2"</td></tr>
          <tr><td>uri</td><td>URI (RFC3986)</td><td><t>"https://www.ietf.org/rfc/rfc3986.txt"</t>
            <t>"geo:13.4125,103.86673" (RFC5870)</t><t>"info:eu-repo/dai/nl/12345"</t><t>"mailto:John.Doe@example.com"</t>
            <t>"tel:+1-201-555-0123" (RFC3966)</t></td></tr>
          <tr><td>uriref</td><td>URI-reference (RFC3986)</td><td>"www.example.com/questions/3456/my-document"</td></tr>
          <tr><td>iri</td><td>internationalized URI (RFC3987)</td><td>"http://www.example.org/D%FCrst"</td></tr>
          <tr><td>iriref</td><td>IRI-reference (RFC3987)</td><td>"www.example.org/D%FCrst"</td></tr>
          <tr><td>uritem</td><td>URI-template (RFC6570)</td><td>"{+x,hello,y}"</td></tr>
          <tr><td>uuid</td><td>UUID (RFC4122)</td><td>"f81d4fae-7dec-11d0-a765-00a0c91e6bf6" </td></tr>
          <tr><td>email</td><td>address (RFC5322)</td><td>"John Doe &lt;jdoe@machine.example&gt;"</td></tr>
          <tr><td>idnemail</td><td>internationalized adress (RFC6531)</td><td> </td></tr>
          <tr><td>hostname</td><td>Host Names (RFC1123)</td><td>"en.wikipedia.org"</td></tr>
          <tr><td>idnhostname</td><td>internationalized Host Names (RFC5890)</td><td> </td></tr>
          <tr><td>jpointer</td><td>JSON pointer (RFC6901)</td><td>"/foo/0"</td></tr>
          <tr><td>rjpointer</td><td>relative JSON pointer (I-D)</td><td>"1/nested/objects"</td></tr>
          <tr><td>regex</td><td>regular expression (ECMA 262)</td><td>"[Ss]mith\\\\b"</td></tr>
          <tr><td>ipv4</td><td>IPv4 address (RFC2673)</td><td>"192.168.1.1"</td></tr>
          <tr><td>ipv6</td><td>IPv6 address (RFC2373)</td><td><t>"2001:0db8:85a3:0000:00</t><t>00:8a2e:0370:7334"</t></td></tr>
          <tr><td>file</td><td>file-hier-part (RFC8089)</td>
            <td><t>"///path/to/file"</t><t>"//host.example.com/path/to/file"</t></td></tr></tbody></table>
        <t>Keywords are not defined as Normalized String (eg. "id", "mandatory", "units"), they can be used as custom DataType
        (eg. "$id", "$mandatory", "$units")</t>
      </section>
      <section><name>Namespace</name>
        <t>The global Namespace includes Namespaces for countries, dependent territories and special areas as defined in
        <xref target="ISO 3166-1 alpha-2"/></t>
        <t>The JsonNamespace for those Namespace is composed by the two digits of the country following by a dot.</t>
        <t><em>Example :</em></t><ul empty="true">
          <li><em>"fr." is the France JsonNamespace</em></li>
          <li><em>"un." is The United Nations JsonNamespace</em></li></ul>
        <t>Each Namespace defines a list of included DataType and Namespace.</t>
      </section>
      <section><name>Custom DataType and Namespace</name>
        <t>Custom DataType and Namespace can be created in any Namespace. </t>
        <t><xref target="table11"/> below presents some examples of custom DataType.</t>
        <table anchor="table11" align="left" pn="table-11"><name>Examples of custom DataType</name><thead>
          <tr><th>JsonDataType</th><th>comment or JsonNTV example</th></tr></thead><tbody>
          <tr><td>"$id"</td><td><t>defined in the global Namespace</t><t>eg. { ":$id": 5426849" }</t></td></tr>
          <tr><td>"$iata"</td><td><t>IATA airport code</t><t>eg. {"Paris Nord:$iata": "CDG"}</t></td></tr>
          <tr><td>"$uic.station"</td><td><t>UIC station code</t><t>eg. {"Nantes station:$uic.station" : "8748100"}</t></td></tr>
          <tr><td>"fr.$city"</td><td><t>DataType "city" in "fr." Namespace</t><t>eg. {":fr.$city" : "Paris"}</t></td></tr>
          <tr><td>"$schemaorg."</td><td><t>"schemaorg" catalog</t><t>eg. { ":$schemaorg.propertyID": "NO2" }</t>
            <t>{ ":$schemaorg.unitText": "mg/m3"}</t></td></tr>
          <tr><td>"$darwincore."</td><td><t>"darwincore" catalog</t><t>eg. { ":$darwincore.acceptedNameUsage": "Tamias minimus" }</t></td>
          </tr></tbody></table>
      </section>
    </section>
    <section><name>Complete ABNF notation</name>
        <figure anchor="Complete-abnf" align="left" suppress-title="false" pn="figure-8">
          <name>Collected ABNF grammar</name><sourcecode type="abnf" markers="false">
            <![CDATA[
; representation of DataType and Namespace (Name and LongName)

DataTypeLongName  = NamespaceParentLongName DataTypeName

NamespaceLongName = NamespaceParentLongName NamespaceName
NamespaceParentLongName = NamespaceLongName

NamespaceName   = [ ["$"] JsonString "." ]      ; REQ2 REQ3
DataTypeName    = TypeBaseName ["[" TypeExtensionName "]"]
TypeBaseName    = ["$"] JsonString              ; REQ3
TypeExtensionName   = JsonString

; JSON representation of NTV entities (JsonNTV)

JsonNTV        = JsonNTVnamed / JsonNTVsimple      ; REQ4

JsonNTVnamed   = beginObject JsonNTVMember endObject
JsonNTVsimple  = JsonNTVvalue

JsonNTVMember  = JsonNTVname nSep JsonNTVvalue

; Extract of JSON grammar used in this document

beginArray    = ws "[" ws
beginObject   = ws "{" ws
endArray      = ws "]" ws
endObject     = ws "}" ws
nSep          = ws ":" ws
vSep          = ws "," ws
ws = *( %x20 / %x09 / %x0A / %x0D )

JsonValue  = JsonValue   ; indicates that rule is defined in RFC8259
JsonString = JsonString  ; indicates that rule is defined in RFC8259

; JSON representation of NTVname and NTVtype (JsonNTVname)

JsonNTVname = NTVname JsonSepType
JsonSepType = [singleSep [JsonNTVtype]]/([listSep] JsonNTVtype)
    ; REQ5 REQ6

NTVname = JsonString

singleSep   = ":"      ; NTVsingle separator
listSep     = "::"     ; NTVlist separator

; JSON representation of NTVType (JsonNTVtype)

JsonNTVtype = [ NTVtypeLongName / NTVtypeRelativeName ]
    ; REQ7

NTVtypeLongName = DataTypeLongName / NamespaceLongName
NTVtypeRelativeName = *NamespaceName (DataTypeName / NamespaceName)
    ; REQ7

; JSON representation of NTVvalue (JsonNTVvalue)

JsonNTVvalue       = JsonNTVsingleValue / JsonNTVlistValue

JsonNTVsingleValue = NTVsingleValue
JsonNTVlistValue   = JsonNTVarrayValue / JsonNTVobjectValue
    ; REQ8 REQ9

JsonNTVarrayValue  = beginArray ListJsonNTVvalue endArray
ListJsonNTVvalue   = [JsonNTV  *( vSep JsonNTV )]
JsonNTVobjectValue = beginObject ListJsonNTVmember endObject
ListJsonNTVmember  = [JsonNTVMember *( vSep JsonNTVMember)]

NTVsingleValue     = JsonValue
            ]]>
      </sourcecode></figure>
    </section>
    <section anchor="JsonNTV format"><name>JSON-NTV equivalence</name>
      <t>This Appendix shows that we can associate with each JsonValue an NTV entity whose JSON representation (JsonNtv) is identical to the JsonValue.</t>
      <t>To do this, let's call NTVarray, NTVobject, NTVnumber, NTVstring, NTVfalse, NTVtrue, NTVnull the entities defined below.</t><ul>
        <li>Json primitives<ul empty="true">
          <li>An NTVprimitive entity (resp. NTVnumber, NTVstring, NTVfalse, NTVtrue or NTVnull) is a Vsingle entity whose NTVvalue is a
          JsonPrimitive (resp. JsonNumber, JsonString, JsonFalse, JsonTrue or JsonNull).</li>
          <li>For example, the NTVstring entity associated with the JsonString "foo" has the following attributes:<ul>
            <li>NTVname: empty,</li>
            <li>NTVtype: "json",</li>
            <li>NTVvalue: "foo".</li></ul></li>
          <li>Given the NTV rules, the JsonNtv is equal to the NTVvalue and therefore the JsonPrimitive. Conversely, an NTV parser converts a JsonPrimitive
          into the corresponding NTVprimitive.</li></ul></li>
        <li>Json Array<ul empty="true">
          <li>The NTVarray entity is the Vlist entity composed of the NTV entities associated with the JsonElements of the JsonArray.</li>
          <li>For example, for a JsonArray composed of the JsonNumber represented by 25 and the JsonArray represented by [1,2],
           the NTVarray has the following attributes:<ul>
            <li>NTVname: None</li>
            <li>NTVtype: None</li>
            <li>NTVvalue: composed of NTVnumber 25 and the NTVarray corresponding to the JsonArray [1,2]</li></ul></li>
          <li>As before, taking into account the NTV rules, the JsonNtv is equal to the json representation of the NTVvalue which is identical to the JsonArray.</li>
          <li>Conversely, an NTV parser converts a JsonArray into the corresponding NTVarray.</li></ul></li>
        <li>JsonObject<ul empty="true">
          <li>Let's call NTVmember the NTV entity associated with the JsonObject corresponding to a JsonMember (key/val).
          This JsonObject has the representation {key: val}.</li>
          <li>If val is a Json Primitive, NTVmember is an NVsingle:<ul>
            <li>NTVname:key</li>
            <li>NTVtype: "json"</li>
            <li>NTVvalue: val</li></ul></li>
          <li>If val is a JsonArray or JsonObject, NTVmember is an NVlist:<ul>
            <li>NTVname:key</li>
            <li>NTVtype: None</li>
            <li>NTVvalue: composed of NTV entities associated with the elements of the JsonArray (or members of the JsonObject)</li></ul></li>
          <li>The NTVobject entity is the Vlist entity composed of the NTVmember entities associated with the JsonMembers of the JsonObject.</li>
          <li>For example, for a JsonObject composed of the JsonMember represented by "foo": 25 and the JsonMember represented by "bar": [1,2],
          the NTVObject will be:<ul>
            <li>NTVname: None</li>
            <li>NTVtype: None</li>
            <li>NTVvalue: composed of NVsingle (NTVname: "foo", NTVtype: "json", NTVvalue: 25) and NVlist (NTVname: "bar", NTVtype: None,
            NTVvalue: composed of NTVnumber 1 and NTVnumber 2).</li></ul></li>
          <li>Similarly to the JsonArray, given the NTV rules, the JsonNtv is equal to the json representation of the NTVvalue which is identical to the JsonObject.</li>
          <li>Conversely, an NTV parser converts a JsonObject into the corresponding NTVObject.</li>
        </ul></li></ul>
      <t>Thus, for all Json entities, we have an equivalence with an NTV entity</t>
    </section>
    <section anchor="mapping"><name>Mapping DataTypes</name>
      <t>This Appendix presents the mapping between DataTypes and the types defined in Data schemas or Data languages.</t>
      <section><name>Table-Schema</name>
        <t>The mapping concerns Table Schema types and formats <xref target="TABLE SCHEMA"/>.
        Parsable and pattern formats (datation) and topojson (location) are not included</t>
        <table anchor="table12" align="left" pn="table-12"><name>Table-Schema types</name><thead>
          <tr><th>type</th><th>format</th><th>DataType</th></tr></thead><tbody>
          <tr><td>string</td><td>default</td><td>string</td></tr>
          <tr><td>string</td><td>email</td><td>email</td></tr>
          <tr><td>string</td><td>uri</td><td>uri</td></tr>
          <tr><td>string</td><td>binary (base64 string)</td><td>base64</td></tr>
          <tr><td>string</td><td>uuid</td><td>uuid</td></tr>
          <tr><td>number</td><td>default</td><td>number</td></tr>
          <tr><td>integer</td><td>default</td><td>int</td></tr>
          <tr><td>boolean</td><td>default</td><td>boolean</td></tr>
          <tr><td>object</td><td>default (json)</td><td>json</td></tr>
          <tr><td>array</td><td>default (json array)</td><td>array</td></tr>
          <tr><td>date</td><td>default (date ISO8601)</td><td>date</td></tr>
          <tr><td>time</td><td>default (time ISO8601)</td><td>time</td></tr>
          <tr><td>datetime</td><td>default (datetime ISO8601 in UTC)</td><td>datetime</td></tr>
          <tr><td>year</td><td>default</td><td>year</td></tr>
          <tr><td>yearmonth</td><td>default</td><td>yearmonth</td></tr>
          <tr><td>duration</td><td>default (lexical duration ISO8601)</td><td>duration</td></tr>
          <tr><td>geopoint</td><td>default (string &quot;lon, lat&quot;)</td><td>pointstr</td></tr>
          <tr><td>geopoint</td><td>array (array [lon, lat])</td><td>point</td></tr>
          <tr><td>geopoint</td><td>object (eg {&quot;lon&quot;: 90, &quot;lat&quot;: 45})</td><td>pointobj</td></tr>
          <tr><td>geojson</td><td>default (geojson spec)</td><td>geojson</td></tr>
          <tr><td>-any-</td><td>-any-</td><td>$xxx (custom type)</td></tr></tbody></table>
      </section>
      <section><name>JSON Schema</name>
        <t>The mapping concerns JSON-schema <xref target="JSON SCHEMA"/> primitive types, defined formats and String-Encoded data .</t>
        <table anchor="table13" align="left" pn="table-13"><name>JSON Schema types</name><thead>
          <tr><th>type</th><th>format</th><th>DataType</th></tr></thead><tbody>
          <tr><td>string</td><td></td><td>string</td></tr>
          <tr><td>string</td><td>date-time</td><td>datetime</td></tr>
          <tr><td>string</td><td>time</td><td>time</td></tr>
          <tr><td>string</td><td>date</td><td>date</td></tr>
          <tr><td>string</td><td>duration</td><td>duration</td></tr>
          <tr><td>string</td><td>email</td><td>email</td></tr>
          <tr><td>string</td><td>idn-email</td><td>idnemail</td></tr>
          <tr><td>string</td><td>hostname</td><td>hostname</td></tr>
          <tr><td>string</td><td>idn-hostname</td><td>idnhostname</td></tr>
          <tr><td>string</td><td>ipv4</td><td>ipv4</td></tr>
          <tr><td>string</td><td>ipv6</td><td>ipv6</td></tr>
          <tr><td>string</td><td>uuid</td><td>uuid</td></tr>
          <tr><td>string</td><td>uri</td><td>uri</td></tr>
          <tr><td>string</td><td>uri-reference</td><td>uriref</td></tr>
          <tr><td>string</td><td>uri-template</td><td>uritem</td></tr>
          <tr><td>string</td><td>iri</td><td>iri</td></tr>
          <tr><td>string</td><td>iri-reference</td><td>iriref</td></tr>
          <tr><td>string</td><td>json-pointer</td><td>jpointer</td></tr>
          <tr><td>string</td><td>relative-json-pointer</td><td>rjpointer</td></tr>
          <tr><td>string</td><td>regex</td><td>regex</td></tr>
          <tr><td>number</td><td></td><td>number</td></tr>
          <tr><td>integer</td><td></td><td>int</td></tr>
          <tr><td>boolean</td><td></td><td>boolean</td></tr>
          <tr><td>object</td><td></td><td>object</td></tr>
          <tr><td>array</td><td></td><td>array</td></tr>
          <tr><td>contentEncoding</td><td>base64</td><td>base64</td></tr>
          <tr><td>contentEncoding</td><td>base32</td><td>base32</td></tr>
          <tr><td>contentEncoding</td><td>base16</td><td>base16</td></tr>
          <tr><td>contentEncoding</td><td>binary</td><td>binary</td></tr>
          <tr><td>null</td><td></td><td>null</td></tr></tbody></table>
      </section>
      <section><name>YANG</name>
        <t>The mapping concerns YANG <xref target="RFC7950"/> build-in types defined.
        Enumeration, leafref, identityref, instance-identifier, union are not included.</t>
        <table anchor="table14" align="left" pn="table-14"><name>YANG types</name><thead>
          <tr><th>type</th><th>DataType</th><th>comments</th></tr></thead><tbody>
          <tr><td>boolean</td><td>boolean</td><td></td></tr>
          <tr><td>decimal64</td><td>decimal64</td><td></td></tr>
          <tr><td>empty</td><td>null</td><td></td></tr>
          <tr><td>int8</td><td>int8</td><td></td></tr>
          <tr><td>int16</td><td>int16</td><td></td></tr>
          <tr><td>int32</td><td>int32</td><td></td></tr>
          <tr><td>int64</td><td>int64</td><td></td></tr>
          <tr><td>uint8</td><td>uint8</td><td></td></tr>
          <tr><td>uint16</td><td>uint16</td><td></td></tr>
          <tr><td>uint32</td><td>uint32</td><td></td></tr>
          <tr><td>uint64</td><td>uint64</td><td></td></tr>
          <tr><td>string</td><td>string</td><td></td></tr>
          <tr><td>bit</td><td>bit</td><td></td></tr>
          <tr><td>binary</td><td>binary</td><td></td></tr></tbody></table>
      </section>
    </section>
    <section anchor="Acknowledgements" numbered="false"><name>Acknowledgements</name>
      <t>TBD</t>
    </section>
    <section anchor="Contributors" numbered="false"><name>Contributors</name>
      <t>TBD</t>
    </section>
 </back>
</rfc>
