Pemetaan Antara JSON dan XML
Pembaca dan penulis yang diproduksi oleh JsonReaderWriterFactory menyediakan API XML melalui konten JavaScript Object Notation (JSON). JSON mengodekan data menggunakan subset harfiah objek JavaScript. Pembaca dan penulis yang diproduksi oleh pabrik ini juga digunakan ketika konten JSON dikirim atau diterima oleh aplikasi Windows Communication Foundation (WCF) menggunakan WebMessageEncodingBindingElement atau WebHttpBinding.
Saat memulai dengan konten JSON, pembaca JSON bertindak dengan cara yang sama seperti yang dilakukan pembaca XML tekstual melalui instans XML. Penulis JSON menulis konten JSON ketika diberikan urutan panggilan yang pada pembaca XML tekstual menghasilkan instans XML tertentu. Pemetaan antara instans XML dan konten JSON dijelaskan dalam topik ini untuk digunakan dalam skenario tingkat lanjut.
Secara internal, JSON direpresentasikan sebagai kumpulan informasi XML saat diproses oleh WCF. Biasanya Anda tidak perlu khawatir dengan representasi internal ini karena hanya pemetaan logis: JSON biasanya tidak dikonversi secara fisik ke XML dalam memori atau dikonversi ke JSON dari XML. Pemetaan berarti API XML digunakan untuk mengakses konten JSON.
Ketika WCF menggunakan JSON, skenario yang biasa adalah bahwa DataContractJsonSerializer secara otomatis dicolokkan oleh perilaku WebScriptEnablingBehavior, atau oleh perilaku WebHttpBehavior jika sesuai. DataContractJsonSerializer memahami pemetaan antara JSON dan kumpulan informasi XML dan bertindak seolah-olah berurusan dengan JSON secara langsung. (Mungkin untuk menggunakan DataContractJsonSerializer dengan pembaca atau penulis XML apa pun, dengan pemahaman bahwa XML sesuai dengan pemetaan berikut.)
Dalam skenario lanjutan, mungkin perlu untuk langsung mengakses pemetaan berikut. Skenario ini terjadi ketika Anda ingin menserialisasi dan mendeserialisasi JSON dengan cara kustom, tanpa mengandalkan DataContractJsonSerializer, atau saat berhadapan dengan jenis Message secara langsung untuk pesan yang berisi JSON. Pemetaan JSON ke XML juga digunakan untuk pengelogan pesan. Saat menggunakan fitur pengelogan pesan di WCF, pesan JSON dicatat sebagai XML sesuai dengan pemetaan yang dijelaskan di bagian berikutnya.
Untuk mengklarifikasi konsep pemetaan, contoh berikut adalah dokumen JSON.
{"product":"pencil","price":12}
Untuk membaca dokumen JSON ini menggunakan salah satu pembaca yang disebutkan sebelumnya, gunakan urutan panggilan XmlDictionaryReader yang sama seperti yang Anda lakukan untuk membaca dokumen XML berikut.
<root type="object">
<product type="string">pencil</product>
<price type="number">12</price>
</root>
Selain itu, jika pesan JSON dalam contoh diterima oleh WCF dan dicatat, Anda akan melihat fragmen XML di log sebelumnya.
Pemetaan Antara JSON dan kumpulan informasi XML
Secara resmi, pemetaan adalah antara JSON seperti yang dijelaskan dalam RFC 4627 (kecuali dengan pembatasan tertentu yang dilonggarkan dan batasan tertentu lainnya ditambahkan) dan kumpulan informasi XML (dan bukan XML tekstual) seperti yang dijelaskan dalam Kumpulan Informasi XML. Lihat topik ini untuk definisi item informasi dan bidang di [kurung siku].
Dokumen JSON kosong memetakan ke dokumen XML kosong, dan dokumen XML kosong memetakan ke dokumen JSON kosong. Pada pemetaan XML ke JSON, spasi kosong sebelumnya dan spasi kosong berikutnya setelah dokumen tidak diizinkan.
Pemetaan ditentukan antara Item Informasi Dokumen (DII) atau Item Informasi Elemen (EII) dan JSON. EII, atau properti [elemen dokumen] DII, disebut sebagai Elemen Akar JSON. Perhatikan bahwa fragmen dokumen (XML dengan beberapa elemen akar) tidak didukung dalam pemetaan ini.
Contoh: Dokumen berikut:
<?xml version="1.0"?>
<root type="number">42</root>
Dan elemen berikut:
<root type="number">42</root>
Keduanya memiliki pemetaan ke JSON. Elemen <root>
ini adalah Elemen Akar JSON dalam kedua kasus.
Selain itu, dalam kasus DII, hal-hal berikut harus dipertimbangkan:
Beberapa item dalam daftar [turunan] tidak boleh ada. Jangan mengandalkan fakta ini saat membaca XML yang dipetakan dari JSON.
Daftar [turunan] tidak menyimpan item informasi komentar.
Daftar [turunan] tidak menyimpan item informasi DTD.
Daftar [turunan] tidak menyimpan item informasi (PI) (deklarasi
<?xml…>
tidak dipertimbangkan sebagai item informasi PI)Kumpulan [notasi] kosong.
Kumpulan [entitas yang tidak diurai] kosong.
Contoh: Dokumen berikut tidak memiliki pemetaan ke JSON karena [turunan] menyimpan PI dan komentar.
<?xml version="1.0"?>
<!--comment--><?pi?>
<root type="number">42</root>
EII untuk Elemen Akar JSON memiliki karakteristik berikut:
[nama lokal] memiliki nilai "root".
[nama namespace layanan] tidak memiliki nilai.
[awalan] tidak memiliki nilai.
[turunan] mungkin berisi EII (yang mewakili Elemen Dalam seperti yang dijelaskan lebih lanjut) atau CII (Item Informasi Karakter seperti yang dijelaskan lebih lanjut) atau tidak satu pun dari keduanya, tetapi tidak keduanya.
[atribut] mungkin berisi item informasi atribut opsional berikut (AII)
Atribut Jenis JSON ("type") seperti yang dijelaskan lebih lanjut. Atribut ini digunakan untuk mempertahankan jenis JSON (string, angka, boolean, objek, array, atau null) dalam XML yang dipetakan.
Atribut Nama Kontrak Data ("__type") seperti yang dijelaskan lebih lanjut. Atribut ini hanya dapat ada jika atribut jenis JSON juga ada dan [nilai yang dinormalisasi] adalah "objek". Atribut ini digunakan oleh
DataContractJsonSerializer
untuk mempertahankan informasi jenis kontrak data - misalnya, dalam kasus polimorfik tempat jenis turunan diserialisasikan dan tempat jenis dasar diharapkan. Jika Anda tidak bekerja denganDataContractJsonSerializer
, dalam banyak kasus, atribut ini diabaikan.[namespace layanan dalam cakupan] berisi pengikatan "xml" ke
http://www.w3.org/XML/1998/namespace
seperti yang diamanatkan oleh spesifikasi infoset.[turunan], [atribut] dan [namespace layanan dalam cakupan] tidak boleh memiliki item apa pun selain yang ditentukan sebelumnya dan [atribut namespace layanan] tidak boleh memiliki anggota, tetapi tidak mengandalkan fakta-fakta ini saat membaca XML yang dipetakan dari JSON.
Contoh: Dokumen berikut tidak memiliki pemetaan ke JSON karena [atribut namespace layanan] tidak kosong.
<?xml version="1.0"?>
<root xmlns:a="myattributevalue">42</root>
AII untuk Atribut Jenis JSON memiliki karakteristik berikut:
- [nama namespace layanan] tidak memiliki nilai.
- [awalan] tidak memiliki nilai.
- [nama lokal] adalah "jenis".
- [nilai yang dinormalisasi] adalah salah satu kemungkinan nilai jenis yang dijelaskan di bagian berikut.
- [ditentukan]
true
. - [jenis atribut] tidak memiliki nilai.
- [referensi] tidak memiliki nilai.
AII untuk Atribut Nama Kontrak Data memiliki karakteristik berikut:
- [nama namespace layanan] tidak memiliki nilai.
- [awalan] tidak memiliki nilai.
- [nama lokal] adalah "__type" (dua garis bawah dan kemudian "jenis").
- [nilai yang dinormalisasi] adalah string Unicode yang valid – pemetaan string ini ke JSON dijelaskan di bagian berikut.
- [ditentukan]
true
. - [jenis atribut] tidak memiliki nilai.
- [referensi] tidak memiliki nilai.
Elemen dalam yang terkandung dalam Elemen Akar JSON atau elemen dalam lainnya memiliki karakteristik berikut:
- [nama lokal] mungkin memiliki nilai apa pun seperti yang dijelaskan lebih lanjut.
- [nama namespace layanan], [awalan], [turunan], [atribut], [atribut namespace layanan], dan [namespace layanan dalam cakupan] tunduk pada aturan yang sama dengan Elemen Akar JSON.
Dalam Elemen Akar JSON dan elemen dalam, Atribut Jenis JSON mendefinisikan pemetaan ke JSON dan kemungkinan [turunan] dan interpretasinya. Atribut [nilai yang dinormalisasi] peka huruf besar/kecil dan harus huruf kecil, dan tidak boleh berisi spasi kosong.
[nilai yang dinormalisasi] dari AII Atribut Jenis JSON | [turunan] yang diizinkan dari EII yang sesuai | Pemetaan ke JSON |
---|---|---|
string (atau tidak adanya AII jenis JSON)string dan tidak adanya AII jenis JSON yang sama membuat string default.Jadi, <root> string1</root> memetakan ke "string1" string JSON. |
0 atau lebih CII | string JSON (JSON RFC, bagian 2.5). Setiap char adalah karakter yang sesuai dengan [kode karakter] dari CII. Jika tidak ada CII, karakter memetakan ke string JSON kosong.Contoh: Elemen berikut memetakan ke fragmen JSON: <root type="string">42</root> Fragmen JSON adalah "42". Pada pemetaan XML ke JSON, karakter yang harus diloloskan memetakan ke karakter yang lolos, semua karakter lainnya dipetakan ke karakter yang tidak lolos. Karakter "/" adalah khusus - karakter tersebut diloloskan meskipun tidak harus (ditulis sebagai "\/"). Contoh: Elemen berikut memetakan ke fragmen JSON. <root type="string">the "da/ta"</root> Fragmen JSON adalah "the \"da\/ta\"". Pada pemetaan JSON ke XML, setiap karakter yang lolos dan karakter yang tidak lolos memetakan dengan benar ke [kode karakter] yang sesuai. Contoh: Fragmen JSON "\u0041BC", memetakan ke elemen XML berikut. <root type="string">ABC</root> String dapat dikelilingi oleh spasi kosong ('ws' di bagian 2 JSON RFC) yang tidak dipetakan ke XML. Contoh: Fragmen JSON "ABC", (ada spasi sebelum kutipan ganda pertama), memetakan ke elemen XML berikut. <root type="string">ABC</root> Setiap spasi kosong di peta XML ke spasi kosong di JSON. Contoh: Elemen XML berikut memetakan ke fragmen JSON. <root type="string"> A BC </root> Fragmen JSON adalah " A BC ". |
number |
1 atau lebih CII | number JSON (JSON RFC, bagian 2.4), mungkin dikelilingi oleh spasi kosong. Setiap karakter dalam kombinasi angka/spasi kosong adalah karakter yang sesuai dengan [kode karakter] dari CII.Contoh: Elemen berikut memetakan ke fragmen JSON. <root type="number"> 42</root> Fragmen JSON adalah 42 (Spasi putih dipertahankan). |
boolean |
4 atau 5 CII (yang sesuai dengan true atau false ), mungkin dikelilingi oleh CII spasi kosong tambahan. |
Urutan CII yang sesuai dengan string "true" dipetakan ke true harfiah, dan urutan CII yang sesuai dengan string "false" dipetakan ke false harfiah. Spasi putih di sekitarnya dipertahankan.Contoh: Elemen berikut memetakan ke fragmen JSON. <root type="boolean"> false</root> Fragmen JSON adalah false . |
null |
Tidak ada yang diizinkan. | null harfiah. Pada pemetaan JSON ke XML, null mungkin dikelilingi oleh spasi kosong ('ws' di bagian 2) yang tidak dipetakan ke XML.Contoh: Elemen berikut memetakan ke fragmen JSON. <root type="null"/> or <root type="null"></root> : Fragmen JSON dalam kedua kasus adalah Null . |
object |
0 atau lebih EII. | begin-object (kurung kurawal kiri) seperti pada bagian 2.2 dari JSON RFC, diikuti oleh baris anggota untuk setiap EII seperti yang dijelaskan lebih lanjut. Jika ada lebih dari satu EII, terdapat pemisah nilai (koma) di antara rekaman anggota. Semua ini diikuti oleh objek akhir (kurung kurawal kanan).Contoh: Elemen berikut memetakan ke fragmen JSON. <root type="object"> <type1 type="string">aaa\</type1> <type2 type="string">bbb\</type2> </root > Fragmen JSON adalah {"type1":"aaa","type2":"bbb"} .Jika Atribut Jenis Kontrak Data ada di pemetaan XML ke JSON, maka Baris Anggota tambahan disisipkan di awal. Namanya adalah [nama lokal] dari Atribut Jenis Kontrak Data ("__type"), dan nilainya adalah atribut [nilai yang dinormalisasi]. Sebaliknya, pada pemetaan JSON ke XML, jika nama baris anggota pertama adalah [nama lokal] dari Atribut Jenis Kontrak Data (yaitu, "__type"), Atribut Jenis Kontrak Data yang sesuai ada di XML yang dipetakan, tetapi EII yang sesuai tidak ada. Perhatikan bahwa baris anggota ini harus terjadi terlebih dahulu di objek JSON agar pemetaan khusus diterapkan. Baris ini mewakili keberangkatan dari pemrosesan JSON biasa, tempat urutan baris anggota tidak signifikan. Contoh: Fragmen JSON berikut memetakan ke XML. {"__type":"Person","name":"John"} XML adalah kode berikut. <root type="object" __type="Person"> <name type="string">John</name> </root> Perhatikan bahwa __type AII ada, tetapi tidak ada __type EII. Namun, jika urutan dalam JSON dibalik seperti yang ditunjukkan dalam contoh berikut. {"name":"John","\_\_type":"Person"} XML yang sesuai ditampilkan. <root type="object"> <name type="string">John</name> <__type type="string">Person</__type> </root> Artinya, __type berhenti memiliki arti khusus dan memetakan ke EII seperti biasa, bukan AII. Aturan meloloskan/tidak meloloskan untuk [nilai yang dinormalisasi] AII saat dipetakan ke nilai JSON sama dengan string JSON, yang ditentukan dalam baris "string" tabel ini. Contoh: <root type="object" __type="\abc" /> contoh sebelumnya dapat dipetakan ke JSON berikut. {"__type":"\\abc"} Pada pemetaan XML ke JSON, [nama lokal] EII pertama tidak boleh "__type". Spasi kosong ( ws ) tidak pernah dihasilkan pada pemetaan XML ke JSON untuk objek dan diabaikan pada pemetaan JSON ke XML.Contoh: Fragmen JSON berikut memetakan ke elemen XML. { "ccc" : "aaa", "ddd" :"bbb"} Elemen XML ditampilkan dalam kode berikut. <root type="object"> <ccc type="string">aaa</ccc> <ddd type="string">bbb</bar> </root > |
array | 0 atau lebih EII | Array awal (kurung siku kiri) seperti pada bagian 2.3 dari JSON RFC, diikuti dengan baris array untuk setiap EII seperti yang dijelaskan lebih lanjut. Jika ada lebih dari satu EII, ada pemisah nilai (koma) di antara baris array. Semua ini diikuti oleh array akhir. Contoh: Elemen XML berikut memetakan ke fragmen JSON. <root type="array"/> <item type="string">aaa</item> <item type="string">bbb</item> </root > Fragmen JSON adalah ["aaa","bbb"] Spasi kosong ( ws ) tidak pernah dihasilkan pada pemetaan XML ke JSON untuk array dan diabaikan pada pemetaan JSON ke XML.Contoh: Fragmen JSON. ["aaa", "bbb"] Elemen XML yang dipetakan. <root type="array"/> <item type="string">aaa</item> <item type="string">bbb</item> </root > |
Baris Anggota berfungsi sebagai berikut:
- Elemen dalam [nama lokal] memetakan ke bagian
string
darimember
seperti yang didefinisikan dalam bagian 2.2 dari JSON RFC.
Contoh: Elemen berikut memetakan ke fragmen JSON.
<root type="object">
<myLocalName type="string">aaa</myLocalName>
</root>
Fragmen JSON berikut ditampilkan.
{"myLocalName":"aaa"}
Pada pemetaan XML ke JSON, karakter yang harus diloloskan di JSON lolos, dan yang lain tidak lolos. Karakter "/", meskipun bukan karakter yang harus diloloskan, tetap lolos (tidak harus lolos pada pemetaan JSON ke XML). Karakter ini diperlukan untuk mendukung format AJAX ASP.NET untuk data
DateTime
di JSON.Pada pemetaan JSON ke XML, semua karakter (termasuk karakter yang tidak lolos, jika perlu) diambil untuk membentuk
string
yang menghasilkan [nama lokal].Elemen dalam [turunan] memetakan ke nilai di bagian 2.2, sesuai dengan
JSON Type Attribute
seperti untukRoot JSON Element
. Beberapa tingkat bersarang EII (termasuk bersarang dalam array) diizinkan.
Contoh: Elemen berikut memetakan ke fragmen JSON.
<root type="object">
<myLocalName1 type="string">myValue1</myLocalName1>
<myLocalName2 type="number">2</myLocalName2>
<myLocalName3 type="object">
<myNestedName1 type="boolean">true</myNestedName1>
<myNestedName2 type="null"/>
</myLocalName3>
</root >
Fragmen JSON berikut merupakan tujuan peta.
{"myLocalName1":"myValue1","myLocalName2":2,"myLocalName3":{"myNestedName1":true,"myNestedName2":null}}
Catatan
Tidak ada langkah pengodean XML dalam pemetaan sebelumnya. Oleh karena itu, WCF hanya mendukung dokumen JSON di mana semua karakter dalam nama kunci adalah karakter yang valid dalam nama elemen XML. Misalnya, dokumen JSON {"<":"a"} tidak didukung karena < bukan nama yang valid untuk elemen XML.
Situasi terbalik (karakter yang valid di XML tetapi tidak di JSON) tidak menyebabkan masalah karena pemetaan sebelumnya mencakup langkah-langkah pelolosan/tidak pelolosan JSON.
Baris Array berfungsi sebagai berikut:
Elemen dalam [nama lokal] adalah "item".
Elem dalam [turunan] memetakan ke nilai di bagian 2.3, sesuai dengan Atribut Jenis JSON seperti yang dilakukan untuk Elemen Akar JSON. Beberapa tingkat bersarangnya EII (termasuk bersarang dalam objek) diizinkan.
Contoh: Elemen berikut memetakan ke fragmen JSON.
<root type="array">
<item type="string">myValue1</item>
<item type="number">2</item>
<item type="array">
<item type="boolean">true</item>
<item type="null"/></item>
</root>
Berikut ini adalah fragmen JSON.
["myValue1",2,[true,null]]