JData
Filnamnstillägg |
.jdt, .jdb
|
---|---|
Internet mediatyp |
applikation/json
|
Skriv kod | TEXT och BINÄR |
Utvecklad av | Qianqian Fang |
Initial release | 25 juli 2019 |
Senaste släppningen | 1.0 Utkast 2 25 juli 2019 |
Typ av format | Datautbyte |
Förlängt från | JSON |
Öppna format ? | Ja |
Hemsida |
JData är en lätt datakommentar och utbytes öppen standard utformad för att representera generella och vetenskapliga datastrukturer som använder mänskligt läsbara (textbaserade) JSON- och (binära) UBJSON -format. JData-specifikationen syftar specifikt till att förenkla utbyte av hierarkiska och komplexa data mellan programmeringsspråk, såsom MATLAB , Python , JavaScript etc. Den definierar en omfattande lista över JSON-kompatibla " name":value-
konstruktioner för att lagra ett brett utbud av datastrukturer, inklusive skalärer, N-dimensionella arrayer, glesa/komplext värderade arrayer, kartor, tabeller, hash, länkade listor, träd och grafer, och stödjer valfri datagruppering och metadata för varje dataelement. De genererade datafilerna är kompatibla med JSON/UBJSON-specifikationer och kan enkelt bearbetas av de flesta befintliga tolkare. JData-definierade annoteringsnyckelord tillåter också lagring av starkt typade binära dataströmmar i JSON, datakomprimering, länkning och referenser.
Historia
Den initiala utvecklingen av JData-anteckningsschemat startade 2011 som en del av utvecklingen av JSONLab Toolbox - en flitigt använd MATLAB/ GNU Octave JSON-läsare/skrivare med öppen källkod. Majoriteten av de kommenterade ND-arraykonstruktionerna, såsom _ArrayType_
, _ArraySize_
och _ArrayData_
, hade implementerats i de tidiga utgåvorna av JSONLab. Under 2015 utvecklades det första utkastet till JData-specifikationen i Iso2Mesh Wiki; sedan 2019 har den efterföljande utvecklingen av specifikationen migrerats till Github .
Släpps
JData version 0.5
V0.5-versionen av JData-specifikationen är det första fullständiga utkastet och offentlig begäran om kommentarer (RFC) av specifikationen, tillgänglig den 15 maj 2019. Denna förhandsversion av specifikationen stöder en majoritet av de datastrukturer som är relaterade till vetenskaplig data och forskning, inklusive ND-matriser, glesa och komplext värderade matriser, binärt datagränssnitt, komprimering på datarekordsnivå, hash, tabeller, träd, länkade listor och grafer. Den beskriver också det allmänna tillvägagångssättet för datalänkning och referens. Referensimplementeringen av denna specifikationsversion släpps som JSONLab v1.8.
JData version 1 utkast 1
Utkast 1 av JData-specifikationen version 1 släpptes den 4 juni 2019. De största ändringarna i denna utgåva inkluderar 1) serialiseringsordningen för ND-matriselement ändras från kolumn-major till rad-major, 2) _ArrayData_-konstruktion för komplex
ND array ändras från en 1-D vektor till en tvåradsmatris, 3) stöder icke-strängvärdade nycklar i hashdata JSON-representationen, och 4) lägg till ett nytt _ByteStream_-objekt för
att serialisera generisk binär data eller binärt stort objekt (BLOB) . Referensimplementeringen av denna specifikationsversion släpps som JSONLab v1.9.
JData version 1 utkast 2
Utkast 2 av JData-specifikationen version 1 släpptes den 25 juli 2019. De stora förändringarna i denna utgåva inkluderar 1) stöd för lagring av specialmatriser via _ArrayShape_-taggen, 2) döpte
alla _ArrayCompression*_-
taggar till _ArrayZip*_
, 3 ) lägg till dedikerade nyckelord för tabelldata: _TableCols_
, _TableRows_
och _TableRecords_
. Referensimplementeringen av denna specifikationsversion släpps som JSONLab v2.0.
JData-anteckningsexempel
Numeriska skalärer
Numeriska värden stöds direkt av antingen JSON- eller UBJSON-specifikationer. Ett numeriskt värde är vanligtvis oförändrat vid konvertering till JData-anteckningen. När du lagrar som filer, lagras de direkt i JSON/UBJSON numeriska värden. Till exempel
Native data | text-JData/JSON-formulär | binär-JData(BJData/ UBJSON ) | |
---|---|---|---|
a=3,14159 |
➡️ |
{ "a" : 3,14159 } |
[{ ] [ U ][ 1 ][ a ][ D ][ 3,15169 ] [ } ]
|
Speciella konstanter och strängar
Det finns några speciella konstanter, nämligen "NaN", "Infinity" och "-Infinity", de kodas som speciella strängnyckelord när de lagras i JSON/text-JData-formaten, men förblir oförändrade när de lagras i det binära JData-formatet
Native data | text-JData/JSON-formulär | binär-JData(BJData/ UBJSON ) | |
---|---|---|---|
a=nan |
➡️ |
{ "a" : "_NaN_" } |
[{ ] [ U ][ 1 ][ a ][ D ][ nan ] [ } ]
|
a=inf |
➡️ |
{ "a" : "_Inf_" } |
[{ ] [ U ][ 1 ][ a ][ D ][ inf ] [ } ]
|
a=-inf |
➡️ |
{ "a" : "-_Inf_" } |
[{ ] [ U ][ 1 ][ D ][ -inf ] [ } ]
|
a=sant |
➡️ |
{ "a" : sant } |
[{ ] [ U ][ 1 ][ a ][ T ] [ } ]
|
a=falskt |
➡️ |
{ "a" : false } |
[{ ] [ U ][ 1 ][ a ][ F ] [ } ]
|
a=noll |
➡️ |
{ "a" : null } |
[{ ] [ U ][ 1 ][ a ][ Z ] [ } ]
|
a="En sträng" |
➡️ |
{ "a" : "En sträng" } |
[{ ] [ U ][ 1 ][ a ][ S ][ U ][ 8 ][ En sträng ] [ } ]
|
Strukturer och hash
Hierarkiska strukturer behövs ofta när man representerar metadata eller enkla listor med namngivna medlemmar. Eftersom "struktur"-datatyp kan mappas direkt till "objekt"-konstruktionen i JSON och UBJSON, behöver de därför inte konverteras när JData-anteckningen används.
Native data | text-JData/JSON-formulär | binär-JData(BJData/ UBJSON ) | |
---|---|---|---|
|
➡️ |
|
|
2D-matris i matrisformat
Enkla 1-dimensionella vektorer stöds i både JSON och UBJSON med hjälp av "array"-konstruktionen. Till exempel
Native data | text-JData/JSON-formulär | binär-JData(BJData/ UBJSON ) | |
---|---|---|---|
a=[ 1,2,3 4,5,6 ] |
➡️ | { "a":[ [1,2,3], [4,5,6] ] } |
[{] [U][1][a] [[] [[] [U][1][U][2][U][3] []] [[] [U][4][U ][5][U][6] []] []] [}] |
liknande 1-D radvektorexemplet ovan, kan vi använda typen [$] och räkna [#] markörer för att förenkla denna array i binär form |
[{] [U][1][a] [[] [[] [$][U] [#][U][3] [1][2][3] [[] [$][U ] [#][U][3] [4][5][6] []] [}] |
||
för att förenkla detta ytterligare, i JData-specifikationen, vi utökade ytterligare UBJSON array count markör |
[{] [U][1][a] [[] [$][U] [#][[] [$][U][#][2] [2][3] [1][2] ][3][4][5][6] [}] |
2D-matriser i det kommenterade formatet
I JData-specifikationen introducerade vi en lätt dataanteckningsmetod för att tillåta en att specificera ytterligare information, såsom datatyp, datastorlek och komprimering, i den lagrade dataposten. Detta uppnås med hjälp av en "strukturliknande" databehållare (en struktur stöds i nästan alla programmeringsspråk) med JData-specificerade mänskligt läsbara underfältsnyckelord. Denna konstruktion är också lätt att serialisera med många av de befintliga JSON/UBJSON-biblioteken.
Till exempel kan ovanstående 2-D-array alternativt lagras med det kommenterade formatet för att tillåta finkornig datalagring
Native data | text-JData/JSON-formulär | binär-JData(BJData/ UBJSON ) | |
---|---|---|---|
|
➡️ |
|
|
3-D och högre dimensionell array
Man kan använda antingen direktformatet eller kommenterat format för att lagra högre dimensionella arrayer, vilket stöds av både JSON/UBJSON, men fördelen med att använda det annoterade formatet för textbaserad JData och det packade array-optimerade formatet för binärt format. -JData blir mer fördelaktigt på grund av snabbare bearbetningshastighet.
Native data | text-JData/JSON-formulär | binär-JData(BJData/ UBJSON ) | |
---|---|---|---|
0
0
a = [ [ [ 1 , 9 , 6 , ], [ 2 , 9 , 3 , 1 ], [ 8 , , 9 , 6 ] ], [ [ 6 , 4 , 2 , 7 ], [ 8 , 5 , 1 , 2 ], [ 3 , 3 , 2 , 6 ] ] ]
|
➡️ |
0
0
{ "a" :[ [ [ 1 , 9 , 6 , ], [ 2 , 9 , 3 , 1 ], [ 8 , , 9 , 6 ] ], [ [ 6 , 4 , 2 , 7 ], [ 8 , 5 , 1 , 2 ] , [ 3 , 3 , 2 , 6 ] ] }
|
[{] [U][1][a] [[] [[] [[] [U][1][U][9][U][6][u][0] []] [[ ] [U][2][U][9][U][3][u][1] []] [[] [U][8][U][0][U][9][ u][6] []] []] [[] [[] [U][6][U][4][U][2][u][7] []] [[] [U] [8][U][5][U][1][u][2] []] [[] [U][3][U][3][U][2][u][6] ] []] []] []] [}] |
Effektivare alternativa format med JData-anteckningar |
00
{ "a" :{ "_ArrayType_" : "uint8" , "_ArraySize_" :[ 2 , 3 , 4 ], "_ArrayData_" :[ 1 , 9 , 6 , , 2 , 9 , 3 , 1 , 8 , , 9 , 6 , 6 , 4 , 2 , 7 , 8 , 5 , 1 , 2 , 3 , 3 , 2 , 6 ] } }
|
[{] [U][1][a] [[] [$][U] [#][[] [$][U][#][3] [2][3][4] [1] ][9][6][0][2][9][3][1][8][0][9][6][6][4][2] [7][8][ 5][1][2][3][3][2][6] [}] |
Arraydata med komprimering
JData-anteckningar stöder datakomprimering för att spara utrymme. Flera ytterligare nyckelord behövs, inklusive "_ArrayZipType" - den komprimeringsmetod som används, "_ArrayZipSize_" - dimensionsvektorn för "förbearbetade" data lagrade i "_ArrayData_"-konstruktionen före komprimering, och "_ArrayZipData_" - den komprimerade databyteströmmen . Till exempel
Native data | text-JData/JSON-formulär | binär-JData(BJData/ UBJSON ) | |
---|---|---|---|
|
➡️ |
|
|
Matriser med komplexa och komplexa värden
En datapost med komplexa värden måste lagras med det "kommenterade arrayformatet". Detta uppnås genom närvaron av _ArrayIsComplex_
och serialiseringen av de komplexa värdena i _ArrayData_-
konstruktionerna i ordningen [[ serialized real-part values], [serialized imag-part values]]
Native data | text-JData/JSON-formulär | binär-JData(BJData/ UBJSON ) | |
---|---|---|---|
a=10,0+6,0j |
➡️ | { "a":{ "_ArrayType_":"dubbel", "_ArraySize_":[1,1], "_ArrayIsComplex_":true, "_ArrayData_":[[10.0],[6.0]] } } |
[{] [U][1][a] [{] [U][11][_ArrayType_] [S][U][6][dubbel] [U][11][_ArraySize_] [[] [U ][2][U][3] []] [U][16][_ArrayIsComplex_] [T] [U][11][_ArrayData_] [[] [[][D][10.0][]] [ [][D][6.0][]] []] [}] [}] |
a=[ 1+2j,3+4j 5+6j,7+8j ] |
➡️ | { "a":{ "_ArrayType_":"uint8", "_ArraySize_":[2,2], "_ArrayIsComplex_":true "_ArrayData_":[[1,3,5,7],[2,4,6 ,8]] } } |
[{] [U][1][a] [{] [U][11][_ArrayType_] [S][U][5][uint8] [U][11][_ArraySize_] [[] [U ][2][U][2] []] [U][16][_ArrayIsComplex_] [T] [U][11][_ArrayData_] [[] [[] [$][U][#][ 4] [1][3][5][7] [[] [$][U][#][4] [2][4][6][8] []] [}] [}] |
Glesa arrayer
Native data | text-JData/JSON-formulär | binär-JData(BJData/ UBJSON ) | |
---|---|---|---|
a=gles(5,4); a(1,1)=2,0; a(2,3)=9,0; a(4,2)=7,0; |
➡️ | { "a":{ "_ArrayType_":"dubbel", "_ArraySize_":[5,4], "_ArrayIsSparse_":true, "_ArrayData_":[[1,2,4],[1,3,2] ,[2.0,9.0,7.0]] } } |
[{] [U][1][a] [{] [U][11][_ArrayType_] [S][U][6][dubbel] [U][11][_ArraySize_] [[] [U ][2][U][3] []] [U][16][_ArrayIsSparse_] [T] [U][11][_ArrayData_] [[] [[][$][U][#][ 3] [1][2][4] [[][$][U][#][3] [1][3][2] [[][$][D][#][3] [2.0][9.0][7.0] []] [}] [}] |
Komplext värderade glesa matriser
Native data | text-JData/JSON-formulär | binär-JData(BJData/ UBJSON ) | |
---|---|---|---|
a=gles(5,4); a(1,1)=2,0+1,2j; a(2,3)=9,0-4,7j; a(4,2)=7,0+1,0j; |
➡️ | { "a":{ "_ArrayType_":"dubbel", "_ArraySize_":[5,4], "_ArrayIsSparse_":true, "_ArrayData_":[[1,2,4],[1,3,2] , [2.0,9.0,7.0],[1.2,-4.7,1.0]] } } |
[{] [U][1][a] [{] [U][11][_ArrayType_] [S][U][6][dubbel] [U][11][_ArraySize_] [[] [U ][2][U][3] []] [U][16][_ArrayIsSparse_] [T] [U][11][_ArrayData_] [[] [[][$][U][#][ 3] [1][2][4] [[][$][U][#][3] [1][3][2] [[][$][D][#][3] [2.0][9.0][7.0] [[][$][D][#][3] [1.2][-4.7][1.0] []] [}] [}] |
Tabeller
Native data | text-JData/JSON-formulär | binär-JData(BJData/ UBJSON ) | |
---|---|---|---|
en tabell utan radnamn
Namn Ålder Grad Höjd ---- ------- ------ ------ Andy 21 BS 69.2 William 21 MS 71.0 Om 22 BE 67.1
|
➡️ |
{ "_TableCols_" : [ "Namn" , "Ålder" , "Grad" , "Höjd" ], " _TableRows_" : [], "_TableRecords_" : [ [ "Andy" , 21 , "BS" , 69.2 ], [ "William" , 21 , "MS" , 71.0 ], [ "Om" , 22 , "BS" , 67.1 ] } }
|
[{] [U][11][_TableCols_] [[] [S][U][4][Namn] [S][U][3][Ålder] [S][U][6][Grad ] [S][U][6][Höjd] []] [U][11][_TableRows_] [[] []] [U][14][_TableRecords_] [[] [[] [S][ U][4][Andy] [U][21] [S][U][2][BS] [d][69.2] []] [[] [S][U][7][William] [U][21] [S][U][2][MS] [d][71.0] []] [[] [S][U][2][Om] [U][22] [S ][U][2][BS] [d][67.1] []] []] [}] |
ange kolumndatatyper | ➡️ |
{ "_TableCols_" : [ { "DataName" : "Name" , "DataType" : "string" }, { "DataName" : "Age" , "DataType" : "int32" }, { "DataName" : "Degree" , "DataType" : "string" }, { "DataName" : "Höjd" , "DataType" : "singel" } ], "_TableRows_" : [], "_TableRecords_" : [ [ "Andy" , 21 , "BS " , 69.2 ], [ "William" , 21 , "MS" , 71.0 ], [ "Om" , 22 , "BS" , 67.1 ] } }
|
[{] [U][11][_TableCols_] [[] [{] [S][U][8][DataName] [S][U][4][Namn] [S][U][8] ][DataTyp] [S][U][6][sträng] [}] [{] [S][U][8][Datanamn] [S][U][3][Ålder] [S][ U][8][DataTyp] [S][U][5][int32] [}] [{] [S][U][8][Datanamn] [S][U][6][Grad] [S][U][8][DataTyp] [S][U][6][sträng] [}] [{] [S][U][8][Datanamn] [S][U][6 ][Höjd] [S][U][8][DataTyp] [S][U][6][singel] [}] []] [U][11][_TableRows_] [[] []] [ U][14][_TableRecords_] [[] [[] [S][U][4][Andy] [U][21] [S][U][2][BS] [d][69.2] []] [[] [S][U][7][William] [U][21] [S][U][2][MS] [d][71.0] []] [[] [S ][U][2][Om] [U][22] [S][U][2][BS] [d][67.1] []] []] [}] |
Träd
Native data | text-JData/JSON-formulär | binär-JData(BJData/ UBJSON ) | |
---|---|---|---|
en träddatastruktur0
root = { id : , data : 10.1 } ├── nod1 = { id : 1 , data : 2.5 } ├── nod2 = { id : 2 , data : 100 } │ ├ = ─ ─ : id .1 _ , data : 9 } │ └── nod2 .2 = { id : 4 , data : 20.1 } └── nod3 = { id : 5 , data :- 9.0 }
|
➡️ |
0
{ "_TreeNode_(root)" : { "id" : , "data" : 10.1 }, "_TreeChildren_" : [ { "_TreeNode_(nod1)" : { "id" : 1 , "data" : 2.5 } }, { "_TreeNode_(nod2)" : { "id" : 2 , "data" : 100 }, "_TreeChildren_" : [ { "_TreeNode_(nod2.1)" : { "id" : 3 , "data" : 9 } } , { "_TreeNode_(nod2.2)" : { "id" : 4 , "data" : 20.1 } ] } , { "_TreeNode_(nod3)" : { "id" : 5 , "data" : -9.0 } } ] }
|
[{] [U][16][_TreeNode_(root)] [{] [U][2][id] [l][0] [U][4][data] [d][10.1] [} ] [U][14][_TreeChildren_] [[] [{] [U][16][_TreeNode_(nod1)] [{] [U][2][id] [l][1] [U][ 4][data] [d][2.5][}] [}] [{] [U][16][_TreeNode_(nod2)] [{] [U][2][id] [l][2] [U][4][data] [d][100][}] [U][14][_TreeChildren_] [[] [{] [U][16][_TreeNode_(nod2.1)] [{] [U][2][id] [l][3] [U][4][data][d][9][}] [}] [{] [U][16][_TreeNode_(nod2. 2)] [{][U][2][id][l][4][U][4][data][d][20.1][}] [}] []] [}] [{ ] [U][16][_TreeNode_(nod3)] [{] [U][2][id] [l][5] [U][4][data] [d][-9.0][}] [}] []] [}] |
Grafer
Native data | text-JData/JSON-formulär | binär-JData(BJData/ UBJSON ) | |
---|---|---|---|
ett riktat grafobjekt 0
head = { id : , data : 10.1 } ⇓ e1 ┌─ nod1 = { id : 1 , data : 2.5 } │ ⇓ e2 │ nod2 = { id : 2 , data : 100 ┝ │ ┝ │ ┝ de3 = _ _ { id : 3 , data : 9 } e7 │ e6 ⇓ e4 │ nod4 = { id : 4 , data : 20.1 } ↲ ⇓ e5 tail = { id : 5 , data :- 9.0 }
|
➡️ |
0
{ "_GraphNodes_" :[ "head" : { "id" : , "data" : 10.1 }, "node1" :{ "id" : 1 , "data" : 2.5 }, "node2" :{ "id" : 2 , "data" : 100 }, "node3" :{ "id" : 3 , "data" : 9 }, "node4" :{ "id" : 4 , "data" : 20.1 }, "tail" : { "id" : 5 , "data" : -9.0 } ], "_GraphEdges_" :[ [ "huvud" , "nod1" , "e1" ], [ "nod1" , "nod2" , "e2" ], [ " nod2" , "nod3" , "e3" ], [ "nod3" , "nod4" , "e4" ], [ "nod4" , "svans" , "e5" ], [ "nod1" , "nod3" , " e6" ], [ "nod2" , "nod4" , "e7" ] ] }
|
[{] [U][12][_GraphNodes_] [{] [U][4][huvud] [{] [U][2][id] [l][0] [U][4][data ] [d][10.1] [}] [U][5][nod1][{] [U][2][id] [l][1] [U][4][data] [d][ 2.5] [}] [U][5][nod2][{] [U][2][id] [l][2] [U][4][data] [d][100] [}] [U][5][nod3][{] [U][2][id] [l][3] [U][4][data] [d][9] [}] [U][5 ][nod4][{] [U][2][id] [l][4] [U][4][data] [d][20.1] [}] [U][4][svans] [ {] [U][2][id] [l][5] [U][4][data] [d][-9.0] [}] [}] [U][12][_GraphEdges_] [[ ] [[] [S][U][4][huvud] [S][U][5][nod1] [S][U][2][e1] []] [[] [S][ U][4][nod1] [S][U][5][nod2] [S][U][2][e2] []] [[] [S][U][4][nod2] [S][U][5][nod3] [S][U][2][e3] []] [[] [S][U][4][nod3] [S][U][5 ][nod4] [S][U][2][e4] []] [[] [S][U][4][nod4] [S][U][4][svans] [S][ U][2][e5] []] [[] [S][U][4][nod1] [S][U][5][nod3] [S][U][2][e6] []] [[] [S][U][4][nod2] [S][U][5][nod4] [S][U][2][e7] []] []] [} ] |
Programvara ekosystem
Textbaserade JData-filer är vanliga JSON-filer och kan lätt tolkas av de flesta befintliga JSON-tolkare. JSON-filerna som innehåller JData-anteckningstaggar rekommenderas att ha suffixet .jdt, även om det också kan sparas som .json. Det finns några små skillnader mellan en .jdt- och en .json-fil, inklusive
- JData .jdt-fil accepterar flera sammanlänkade JSON- objekt i en enda fil
- JData .jdt-strängar accepterar nya rader inuti en sträng medan JSON-specifikationen kräver att nya radstecken kodas som "\n"; de flesta JSON-tolkare kan bearbeta nya rader i strängen via det "avslappnade" parsningsläget.
Det binära gränssnittet för JData-specifikationen definieras via Binary JData (BJData)-specifikationen - ett format som till stor del härrör från UBJSON Specification Draft 12. BJData-formatet innehåller tre utökade funktioner jämfört med UBJSON: 1) BJData introducerar 4 nya datamarkörer ( [ u]
för "uint16"
, [m]
för "uint32"
, [M]
för "uint64"
och [h]
för "float16"
) som inte stöddes i UBJSON, 2) BJData introducerar en optimerad typad ND-arraybehållare, och 3) BJData slutar mappa NaN/Infinity
till null
( [Z]
), istället använder den deras respektive IEEE754-representationer.
Lättvikts Python JData-kodare/avkodare, pyjdata, är tillgänglig på PyPI , Debian/Ubuntu och GitHub. Det kan konvertera ett brett utbud av komplexa datastrukturer, inklusive dict, array, numpy ndarray, till JData-representationer och exportera data som JSON- eller UBJSON-filer. BJData Python-modulen, pybj, som möjliggör läsning/skrivning av BJData/UBJSON-filer, är också tillgänglig på PyPI, Debian/Ubuntu och GitHub.
För MATLAB och GNU Octave är JSONLab v2.0 referensimplementeringen för den senaste JData-specifikationen och är tillgänglig på Debian/Ubuntu, Fedora och GitHub. JSONLab-verktygslådan distribueras också via MATLAB File Exchange, och är bland de mest populära nedladdningspaketen och namnges i Popular File 2018.
För JavaScript har en JData-kodare/avkodare med namnet jsdata utvecklats för att bearbeta JData-kodade filer på webbsidor. En framträdande tillämpning av jsdata är MCX Cloud, en NIH -finansierad molnbaserad Monte Carlo fotontransportsimuleringsplattform.
Kompakta funktioner för kodning/avkodning av JSON-filer som innehåller JData-annoteringar har också implementerats i C/C++ som en del av fotontransportsimulatorn Monte Carlo eXtreme.