Model objek JSON yang cepat dan hemat memori, dengan dukungan untuk penguraian dan penulisan secara efisien dalam format yang sesuai dengan JSON.
Perpustakaan ini hanya tergantung pada repositori Neslib. Ini dimasukkan sebagai submodule dengan repositori ini.
Titik masuk utama ke perpustakaan ini adalah antarmuka IJsonDocument . Ini digunakan untuk parsing, memuat dan menyimpan dokumen JSON dan menyediakan akses ke model objek JSON. Anda dapat mengurai string JSON sebagai berikut:
var
Doc: IJsonDocument;
begin
Doc := TJsonDocument.Parse( ' { "Answer" : 42 } ' );
end ;Perhatikan bahwa, tidak seperti spesifikasi JSON resmi, perpustakaan ini tidak memerlukan kutipan di sekitar tombol kamus (selama kunci tidak berisi spasi atau karakter non-pengenal lainnya). Jadi berikut ini juga valid:
Doc := TJsonDocument.Parse( ' { Answer : 42 } ' ); Anda juga dapat menggunakan metode Load untuk memuat dari file atau streaming.
Di sisi output, Anda menggunakan Save untuk menyimpan ke file atau stream, atau ToJson untuk output ke string JSON.
Anda juga dapat membuat dokumen JSON baru dari awal menggunakan CreateArray atau Metode CreateDictionary :
var
Doc: IJsonDocument;
begin
Doc := TJsonDocument.CreateArray;
Doc.Root.Add( 42 );
end ;Seperti yang dapat Anda lihat dalam contoh ini, Anda mengakses model objek dokumen JSON melalui properti root.
Di jantung model objek JSON adalah tipe TJsonValue . Ini adalah catatan yang dapat menahan nilai JSON apa pun.
Ini menyediakan berbagai operator konversi implisit untuk mengonversi TJsonValue ke jenis lain (Delphi). Selain itu, ada berbagai metode To* yang mencoba mengonversi TJsonValue tetapi mengembalikan nilai default yang disediakan jika konversi gagal.
Anda (dapat) tidak pernah membuat sendiri TJsonValue ; Satu -satunya cara untuk membuat TJsonValue adalah dengan menambahkan nilai ke array atau kamus JSON:
var
Doc: IJsonDocument;
begin
Doc := TJsonDocument.CreateArray;
Doc.Root.Add( 42 );
end ; Contoh ini menambahkan TJsonValue (dengan nilai 42) ke array JSON. Untuk membuat array kamus baru, Anda menggunakan metode AddArray atau AddDictionary sebagai gantinya:
var
Doc: IJsonDocument;
Dict: TJsonValue;
begin
Doc := TJsonDocument.CreateArray;
Dict := Doc.Root.AddDictionary;
Dict.AddOrSetValue( ' answer ' , 42 );
end ;Ini menciptakan kamus baru dan menambahkannya ke array root. Kemudian, nilai 42 ditambahkan ke kamus ini dengan nama 'Jawaban'.
Untuk memeriksa jenis nilai, gunakan properti TJsonValue.ValueType atau salah satu metode TJsonValue.Is* .
Saat mencoba menggunakan metode seperti Add (atau AddOrSetValue ) pada nilai -nilai yang bukan array (atau kamus), pengecualian akan dinaikkan.
Namun, mengakses item dalam array (menggunakan properti Items ) atau nilai -nilai dalam kamus (menggunakan properti Values ) tidak akan pernah menghasilkan pengecualian, bahkan jika indeks array di luar batas. Hal ini memungkinkan untuk merantai beberapa array/kamus akses bersama -sama tanpa harus memeriksa validitas setiap langkah perantara. Misalnya:
I := Doc.Root.Items[ 3 ].Values[ ' foo ' ].Values[ ' bar ' ].Items[ 4 ].ToInteger( 0 );Ini akan selalu berhasil, tetapi mengembalikan 0 jika salah satu nilai menengah tidak tersedia.
Antarmuka IJsonDocument memudahkan untuk membaca dan menulis JSON ke dalam model objek dokumen.
Namun, Anda juga dapat memilih untuk membaca atau menulis JSON secara manual jika Anda lebih suka (misalnya untuk menghindari harus memuat model objek ke dalam memori). Anda dapat melakukan ini dengan antarmuka IJsonReader dan IJsonWriter di unit Neslib.Json.IO .
Antarmuka ini sepenuhnya independen dari implementasi DOM apa pun dan bahkan tidak memerlukan unit Neslib.Json . Menggunakan antarmuka ini sedikit lebih rumit dan membutuhkan lebih banyak pekerjaan. Lihat unit Neslib.Json.IO untuk informasi lebih lanjut.
Ada juga implementasi JSONPATH seperti XPath yang dapat Anda gunakan untuk meminta dokumen JSON.
Tidak ada spesifikasi resmi JSONPATH, tetapi versi yang paling banyak digunakan tampaknya adalah yang dikembangkan oleh Stefan Goessner.
Jsonpath terlihat seperti:
$.store.book[0].titleatau
$['store']['book'][0]['title'] Kedua representasi itu identik: Anda dapat menggunakan notasi DOT ( . ) Atau braket ( [] ) untuk menunjukkan anak -anak dari sebuah kamus. Kurung juga dapat digunakan dengan indeks numerik untuk menunjukkan anak -anak dari array berdasarkan indeks.
JsonPath hanya menggunakan satu kutipan (') di dalam tanda kurung. Kami juga mengizinkan penawaran ganda (") karena ini lebih mudah digunakan dalam string Delphi.
Pendeknya:
$ yang menunjukkan root, diikuti oleh nol atau lebih operator anak ( . Atau [] ). A $ dengan sendirinya cocok dengan seluruh dokumen.* atau '*' ) untuk mencocokkan semua anak. Misalnya, $.store.book[*].author cocok dengan penulis semua buku di toko.. ), Dot ganda ( .. ) dapat digunakan untuk mencari keturunan apa pun alih -alih anak -anak dekat. Misalnya, $..author cocok dengan semua penulis, terlepas dari kedalaman. Ini disebut keturunan rekursif.$.store.book[0,2,3] cocok dengan buku pertama, ketiga dan keempat.[Start:End:Step] untuk mencocokkan irisan (kisaran) anak -anak. Ini cocok dengan semua anak dari indeks Start hingga (tetapi tidak termasuk) End , menggunakan ukuran Step yang diberikan (biasanya 1). Semua opsional, tetapi setidaknya satu nilai (dan usus besar) harus diberikan:Start dihilangkan, itu tersirat ke 0. Nilai negatif menunjukkan offset dari akhir array.End dihilangkan, irisan ekstrak melalui ujung array. Nilai negatif menunjukkan dan mengimbangi dari akhir array.Step dihilangkan, IS tersirat menjadi 1.List[2:] cocok dengan elemen ketiga dan semua berikut.List[-2:] cocok dengan dua elemen terakhir.List[:2] cocok dengan dua elemen pertama.List[:-2] cocok dengan semua kecuali dua elemen terakhir.List[2:-2] cocok dengan semua elemen tetapi dua yang pertama dan dua terakhir.List[-4:-2] cocok dengan elemen ke-3 dan ke-4 dari akhir.List[::2] cocok dengan semua elemen dengan indeks genap.JsonPath juga memiliki operator @ untuk mengizinkan ekspresi skrip khusus. Kami tidak mendukung operator ini.
Contoh dokumen:
{ "store" : {
"book" : [
{ "category" : " reference " ,
"author" : " Nigel Rees " ,
"title" : " Sayings of the Century " ,
"price" : 8.95
},
{ "category" : " fiction " ,
"author" : " J. R. R. Tolkien " ,
"title" : " The Lord of the Rings " ,
"isbn" : " 0-395-19395-8 " ,
"price" : 22.99
}
],
"bicycle" : {
"color" : " red " ,
"price" : 19.95
}
}
}Contoh jalur:
| Ekspresi | Hasil |
|---|---|
$ | Cocok dengan dokumen root (nilai tunggal) |
$..* | Mencocokkan semua anggota dalam dokumen (banyak nilai) |
$.store.book[*].author | Para penulis semua buku di toko |
$..author | Semua penulis |
$.store.* | Semua hal yang ada di toko (2 buku dan sepeda) |
$.store..price | Harga semua yang ada di toko |
$..book[2] | Buku ketiga |
$..book[-1:] | Buku terakhir secara berurutan |
$..book[:2] | Dua buku pertama |
API JsonPath pendek dan sederhana. Ini terdiri dari catatan TJsonPath dengan hanya beberapa metode.
Untuk pencocokan satu kali, gunakan metode Match statis:
var
Doc: IJsonDocument;
Matches: TArray<TJsonValue>;
begin
Doc := TJsonDocument.Load(...);
Matches := TJsonPath.Match(Doc, ' $.store.book[*].author ' );
end ;Jika Anda berencana untuk menggunakan jalur yang sama pada beberapa dokumen (sub), maka lebih cepat untuk menguraikan jalur sekali, dan kemudian menerapkannya beberapa kali:
var
Doc1, Doc2: IJsonDocument;
Path: TJsonPath;
Matches1, Matches2: TArray<TJsonValue>;
begin
Doc1 := TJsonDocument.Load(...);
Doc2 := TJsonDocument.Load(...);
Path := TJsonPath.Create( ' $.store.book[*].author ' );
Matches1 := Path.Match(Doc1);
Matches2 := Path.Match(Doc2);
end ;Anda juga dapat menjalankan jalur di sub-pohon:
var
Doc: IJsonDocument;
Store: TJsonValue;
Matches: TArray<TJsonValue>;
begin
Doc := TJsonDocument.Load(...);
Store := Doc.Root.Values[ ' store ' ];
Matches := TJsonPath.Match(Store, ' $.book[*].author ' );
end ; Jika Anda hanya tertarik pada pertandingan tunggal (atau yang pertama), maka Anda dapat menggunakan MatchSingle sebagai gantinya:
var
Doc: IJsonDocument;
Match: TJsonValue;
begin
Doc := TJsonDocument.Load(...);
if (TJsonPath.MatchSingle(Store, ' $.book[*] ' , Match)) then
...
end ; Semua manajemen memori di perpustakaan JSON ini otomatis. Antarmuka IJsonDocument memiliki semua TJsonValue dan menghancurkannya ketika dokumen dihancurkan (keluar dari ruang lingkup).
Satu -satunya hal yang perlu Anda waspadai adalah bahwa Anda tidak boleh menggunakan catatan tjsonvalue lagi setelah dokumen dihancurkan. Melakukan hal itu akan menyebabkan perilaku yang tidak terdefinisi dan mungkin crash.
Anda dapat menyesuaikan beberapa perilaku menggunakan definisi bersyarat ini:
JSON_UTF8 : untuk menggunakan UTF8String bukan String di mana -mana. Semua string akan diperlakukan sebagai string UTF-8 8-bit, bukan string unicode 16-bit. Ini mengurangi konsumsi memori dan mempercepat sedikit parsing. Namun, ini berarti Anda harus menggunakan perpustakaan JSON ini dengan UTF8Strings juga, jika tidak, Delphi akan secara implisit mengonversi antara string Unicode dan UTF8Strings, yang dapat merusak kinerja.JSON_STRING_INTERNING : Untuk mengaktifkan string magang untuk tombol kamus. Ini mengurangi konsumsi memori jika kunci yang sama digunakan berkali -kali (yang biasa terjadi ketika JSON diekspor dari database), tetapi sedikit lebih lambat. Unit neslib.json menyatakan tipe JsonString sebagai String atau UTF8String , tergantung pada definisi JSON_UTF8 . Namun, ini tidak berarti bahwa Anda harus menggunakan JsonString juga. Jika Anda tidak peduli dengan definisi JSON_UTF8 , maka Anda bisa menggunakan string reguler dengan perpustakaan ini.
Neslib.json dilisensikan di bawah lisensi BSD yang disederhanakan.
Lihat lisensi.txt untuk detailnya.