Konverter XML ke JSON

Ubah XML ke JSON atau JSON ke XML, dengan atribut @, #text, larik yang ditentukan seluruh dokumen, serta baris dan kolom tempat XML tidak well-formed.

Indentasi
Masukan
Keluaran

Keluaran akan muncul di sini

Apa yang dilakukan alat ini

XML cenderung datang dari sistem yang tidak dipilih siapa pun: respons SOAP, umpan RSS, berkas konfigurasi, ekspor dari sesuatu yang lebih tua daripada JSON. Kode yang harus memakainya menginginkan JSON. Kebalikannya sama umumnya, yaitu payload JSON yang ditujukan ke sistem yang hanya menerima XML. Halaman ini mengonversi ke kedua arah, di peramban Anda, dan membaca keduanya dengan satu kumpulan aturan yang tetap, sehingga kedua arah sepakat tentang arti setiap kunci.

Yang membedakannya adalah bahwa bentuk JSON diputuskan dari seluruh dokumen, bukan dari elemen mana pun yang sedang dibaca, dan halaman ini mengatakannya. Di mana pun keputusan itu memberi elemen bentuk yang berbeda dari bentuk yang akan dimilikinya jika berdiri sendiri, pemberitahuan di bawah keluaran menyebut jalurnya serta baris dan kolom tempat keputusan itu pertama kali berlaku. Apa yang tidak punya tempat di JSON, seperti komentar atau urutan konten campuran, diumumkan dengan cara yang sama alih-alih lenyap, dan di arah sebaliknya setiap penulisan ulang yang dipaksakan XML pada JSON Anda disebutkan di tempat penulisan ulang itu terjadi.

Aturannya: @ untuk atribut, #text untuk teks

Ada satu kumpulan aturan, dan tidak ada pengaturan yang mengubahnya. Atribut menjadi kunci yang dieja @ diikuti nama atribut itu, dan teks yang harus berbagi elemennya dengan hal lain apa pun ditaruh di bawah kunci #text. Baik @ maupun # tidak boleh mengawali nama XML, jadi tidak ada kunci yang ditulis dengan cara ini yang bisa disangka elemen anak, dan itulah yang memungkinkan JSON yang sama dibaca kembali menjadi XML tanpa menebak. Diterapkan pada katalog kecil:

  • Elemen akar adalah satu-satunya kunci di tingkat teratas: dokumen yang elemen akarnya catalog menjadi objek dengan kunci tunggal "catalog".
  • Elemen yang tidak berisi apa pun selain teks adalah teks itu sendiri: <title>Midnight Rain</title> menjadi "title": "Midnight Rain".
  • Atribut adalah kunci di samping elemen anak: <book id="bk101"> memberi buku itu "@id": "bk101", dan setiap elemen anak menyusul sebagai kunci, dalam urutan kemunculan pertamanya.
  • Elemen yang memiliki atribut dan teks menyimpan teksnya di bawah #text: <price currency="USD">44.95</price> menjadi "price": {"@currency": "USD", "#text": 44.95}.
  • Elemen yang berulang di bawah satu induk menjadi larik: buku dengan elemen author yang muncul dua kali memiliki "author": ["Gambardella, Matthew", "Knorr, Stefan"].
  • Nama dipertahankan persis seperti ditulis, lengkap dengan prefiksnya: <dc:title> menjadi kunci "dc:title", deklarasi ruang-nama menjadi kunci atribut seperti "@xmlns:dc", dan tidak ada yang dipetakan ke URI ruang-nama.

Entitas dan referensi karakter didekode, jadi &amp; tiba sebagai & dan &#233; sebagai é, dan bagian CDATA hanyalah teks. Spasi yang berdiri sendiri di antara elemen adalah tata letak dan dibuang; setiap ruas teks lainnya dipertahankan utuh dan tidak pernah dipangkas. Dua normalisasi yang diterapkan setiap pengurai XML yang mematuhi standar tetap berlaku lebih dulu: carriage return yang diketik di dalam teks tiba sebagai line feed, dan tab atau pemutus baris yang diketik di dalam nilai atribut tiba sebagai spasi. Referensi karakter adalah cara dokumen mempertahankan keduanya.

Mengapa seluruh dokumen yang memutuskan bentuknya

Konverter yang memutuskan elemen satu per satu menuliskan pengarang buku pertama sebagai larik, karena jumlahnya dua, dan pengarang buku kedua sebagai string, karena jumlahnya satu. Elemen yang membawa atribut menjadi objek di satu rekaman dan teks biasa di rekaman berikutnya. Kode yang ditulis untuk rekaman pertama gagal pada rekaman kedua, dan tidak ada apa pun sepanjang prosesnya yang memberi tahu bahwa bentuknya bisa berubah.

Karena itu bentuk diputuskan per jalur: nama-nama elemen dari akar turun sampai ke suatu elemen, ditulis /catalog/book/author, tanpa posisi di dalamnya, sehingga setiap pengarang dari setiap buku berada di satu jalur. Setiap elemen di satu jalur ditimbang sekaligus:

  • Larik. Jika elemen itu berulang di bawah satu induk mana pun, setiap elemen di jalur tersebut ditulis sebagai larik, termasuk yang muncul sendirian.
  • Objek. Jika ada elemen di jalur itu yang membawa atribut atau elemen anak, setiap elemen di jalur tersebut ditulis sebagai objek, termasuk yang hanya berisi teks, dan menyimpan teksnya di bawah #text.
  • Nilai. Jalur dibaca sebagai angka hanya jika setiap nilai di jalur itu dapat dikonversi, dan sebagai boolean hanya jika setiap nilainya true atau false, menurut aturan yang dijelaskan di bawah, pada bagian tentang angka dan boolean.
  • Elemen kosong. Elemen kosong tidak ikut dalam keputusan-keputusan ini, dan mengambil jenis yang ditetapkan untuk jalurnya.

Di mana pun hasilnya berbeda dari bentuk elemen itu seandainya berdiri sendiri, halaman ini mengatakannya satu kali untuk jalur tersebut, beserta baris dan kolom elemen pertama yang diubahnya. Dalam katalog yang salah satu bukunya memiliki beberapa pengarang dan buku lainnya hanya satu, pengarang tunggal itu tetap berupa larik; di tempat satu harga membawa atribut currency dan harga lain tidak, harga yang polos tetap berupa objek, dengan teksnya di bawah #text. Keduanya diumumkan, jadi tidak satu pun mengejutkan kode yang membacanya.

Sampel dengan satu rekaman, dan bidang "Selalu larik"

Bentuknya hanya bisa sebaik dokumen yang menjadi dasar keputusannya. Tempel katalog yang berisi satu buku, dan buku itu menjadi objek, pengarang satu-satunya menjadi string dan harganya menjadi angka, sedangkan katalog yang sama dengan buku kedua di sampingnya menjadikan buku-bukunya larik. Jalur yang di mana-mana muncul sekali saja dalam apa yang Anda tempel tetap menjadi nilai tunggal, dan jalur yang semua nilainya kebetulan dapat dikonversi tetap berupa angka sampai tiba dokumen yang memuat kode pos berawalan nol. JSON itu dapat diandalkan tepat sejauh sampelnya representatif, jadi tempel lebih dari satu rekaman bila memungkinkan.

Untuk larik, ada jalan keluar yang tidak bergantung pada sampel. Ketikkan di "Selalu larik" nama elemen atau jalur yang harus menjadi larik apa pun yang ditunjukkan dokumen, dipisahkan koma atau spasi, dan setiap jalur yang cocok dengan salah satu entri ditulis sebagai larik di mana-mana, bahkan di tempat ia muncul sekali saja:

  • Nama polos seperti item cocok dengan setiap jalur yang berakhir pada elemen bernama item, di mana pun letaknya.
  • Jalur seperti /rss/channel/item cocok dengan jalur itu saja, ditulis dengan cara yang sama seperti jalur di bawah keluaran ditulis, jadi Anda bisa menyalinnya dari sana.
  • Pencocokannya persis: huruf besar-kecil diperhitungkan, dan prefiks adalah bagian dari nama, jadi Item tidak cocok dengan item mana pun dan link tidak cocok dengan atom:link mana pun.
  • Setiap jalur yang dijadikan larik oleh bidang ini diumumkan seperti keputusan lainnya. Entri yang bukan nama dan bukan jalur, serta entri yang tidak cocok dengan elemen apa pun di dokumen, dicantumkan di bawah bidang itu, dan entri yang memang berlaku tetap diterapkan.

Bidang ini milik arah "XML ke JSON". Apa yang Anda ketik tetap ada ketika Anda membalik arah lalu kembali, dan seperti setiap pengaturan di halaman ini, isinya tidak disimpan antarkunjungan. Nilai tidak punya bidang semacam itu: mematikan "Konversi angka dan boolean" adalah cara menjaga jalur yang harus tetap berupa teks apa pun isi sampelnya, dengan akibat setiap nilai lain juga menjadi teks.

Angka, boolean, dan mengapa 02134 tetap berupa teks

Segala sesuatu dalam XML adalah teks, dan mengubah teks yang tampak numerik menjadi angka JSON biasanya yang Anda inginkan. Itu juga cara kode pos 02134 menjadi 2134, dan cara nomor pesanan yang panjang kehilangan digit terakhirnya. Aturan di sini adalah aturan yang dipakai konverter CSV di situs ini, dan ia tidak memerlukan daftar kasus khusus: teks menjadi angka hanya jika angka itu, bila ditulis kembali, mengeja teksnya persis. 42 memenuhinya, jadi ia dikonversi. 02134 tidak, begitu pula 1.50, +5, 1e5, atau bilangan bulat yang terlalu panjang sehingga double tidak dapat menyimpan setiap digitnya. Boolean adalah persis true dan false, dalam huruf kecil.

Yang ditambahkan halaman ini adalah bahwa aturan itu diberlakukan pada seluruh jalur sekaligus. Jalur dibaca sebagai angka hanya jika setiap nilainya dapat dikonversi, dan sebagai boolean hanya jika setiap nilainya boolean; satu nilai yang akan kehilangan digit, atau angka dan boolean yang bertemu di satu jalur, membuat setiap nilai di sana tetap berupa teks. Setiap nama atribut di satu jalur diputuskan tersendiri. Jalur yang tetap berupa teks padahal sebagian nilainya bisa dikonversi diumumkan dengan menyebut jalurnya, dan untuk atribut, jalurnya berakhir pada atribut itu, seperti pada /catalog/book/@id.

"Konversi angka dan boolean" menyala saat halaman dibuka, sebagaimana sakelar padanannya di halaman CSV, dan mematikannya menulis setiap nilai sebagai teks. Nilai deklarasi ruang-nama tidak pernah dibaca sebagai angka, baik sakelar itu menyala maupun mati, karena standar Namespaces in XML mendefinisikan nilai itu sebagai nama ruang-nama, yang merupakan teks.

Elemen kosong, dan null yang dinyatakan dokumen itu sendiri

  • Elemen kosong mengambil jenis yang ditetapkan untuk jalurnya. Di jalur teks, ia menjadi string kosong. Di jalur angka atau boolean, ia menjadi null, dan halaman ini mengatakannya, karena jika berdiri sendiri elemen itu akan menjadi teks kosong.
  • Kosong berarti tidak berisi apa pun sama sekali: <zip> </zip> berisi spasi, dan spasi adalah teks.
  • Jalur yang setiap elemennya kosong berupa teks, jadi masing-masing elemen itu menjadi string kosong. Tidak ada apa pun di sana yang terbaca sebagai angka, dan null akan menjadi informasi yang tidak pernah diberikan dokumen.
  • Di jalur yang ditulis sebagai objek, elemen kosong juga membawa #text, kosong atau null menurut aturan yang sama, di mana pun ada elemen lain di jalur itu yang berisi teks: di samping <price currency="USD">5</price>, <price/> menjadi {"#text": null}. Di tempat tidak ada elemen di jalur itu yang berisi teks, seperti elemen gambar yang hanya membawa atribut src, tidak satu pun dari elemen itu membawa #text.

Dokumen juga bisa menyatakan null sendiri. Elemen yang ditandai xsi:nil="true", dengan prefiks itu terikat pada ruang-nama XML Schema instance, bernilai null di jalur mana pun, bagaimanapun "Konversi angka dan boolean" disetel. Penandaan itu adalah cara dokumen mengatakan null alih-alih data, jadi baik atributnya maupun deklarasi ruang-nama yang tidak mengikat hal lain tidak muncul di JSON. Prefiks apa pun yang terikat pada ruang-nama itu bisa dipakai, dan i:nil="1" mengatakan hal yang sama; xsi:nil="false" adalah data biasa, dan elemen yang ditandai nil tetapi masih berisi konten dibiarkan apa adanya, karena membacanya sebagai null akan membuang konten itu tanpa sepatah kata pun.

Apa yang tidak punya tempat di JSON, diumumkan alih-alih hilang

Sebagian isi dokumen XML tidak punya tempat di JSON. Yang membawa makna diumumkan di bawah keluaran alih-alih dibuang diam-diam:

  • Urutan konten campuran. Dalam <p>Hello <b>world</b>, again</p> teksnya dikumpulkan di bawah #text sebagai "Hello , again" dan elemen b di bawah "b": setiap karakter dan setiap elemen tetap ada, tetapi urutan asalnya tidak. Elemen anak yang namanya berselang-seling kehilangan urutannya dengan cara yang sama. Hal ini diumumkan satu kali untuk jalur elemen yang memiliki konten itu, dan hanya di tempat urutannya benar-benar hilang, jadi <p><b>Note:</b> the rest</p> tidak memunculkan apa pun, karena urutan kuncinya mempertahankannya.
  • Komentar dan instruksi pemrosesan. Keduanya dihilangkan, dengan satu pemberitahuan untuk setiap jenis yang menyebut berapa jumlahnya dan di mana letak yang pertama.
  • DOCTYPE. Ia juga dihilangkan, dan pemberitahuannya mengatakan bahwa DTD tidak diterapkan: nilai bawaan yang dideklarasikan DTD untuk atribut tidak ada di JSON, karena alat ini tidak membaca DTD.
  • Deklarasi XML di bagian atas. Ia dihilangkan tanpa pemberitahuan, karena ia menjelaskan bagaimana teks dikodekan, bukan apa datanya.

JSON kembali ke XML: XML terdekat, dan setiap penulisan ulang disebutkan

Balik arahnya dan aturan yang sama berjalan ke arah sebaliknya: kunci @ menjadi atribut, #text menjadi teks elemennya, larik menjadi satu elemen untuk setiap anggota, dan kunci lain apa pun menjadi elemen anak, dengan elemen anak mengikuti urutan kunci-kuncinya. Null ditulis sebagai elemen kosong yang ditandai xsi:nil="true", dengan ruang-nama XML Schema instance dideklarasikan satu kali pada elemen akar dan hanya ketika ada null yang ditulis, sehingga mengonversi kembali memberi null lagi, bukan string kosong. Selain JSON yang tidak dapat diurai, atau yang bersarang terlalu dalam untuk dikonversi, tidak ada yang ditolak. Di tempat JSON Anda memiliki bentuk yang tidak dapat ditampung XML apa adanya, XML terdekat yang well-formed ditulis dan penulisan ulangnya disebutkan di bawah keluaran, pada JSONPath yang bisa Anda tempel ke Penguji JSONPath di situs ini:

  • Apa pun selain satu elemen akar saja, entah beberapa kunci di tingkat teratas, tidak ada sama sekali, larik di tingkat teratas, atau nilai polos, ditulis di dalam <root>.
  • Kunci yang bukan nama XML ditulis dengan nama terdekat yang tidak dipakai kunci lain di sampingnya: first name menjadi first_name, dan 1st menjadi _1st.
  • Anggota larik yang tidak dinamai kunci mana pun, entah berada di dalam larik lain atau di tingkat teratas, ditulis sebagai elemen <item>.
  • Kunci @ atau #text yang berisi objek atau larik ditulis sebagai elemen anak, karena baik atribut maupun teks tidak dapat menampungnya.
  • Kunci @ yang berisi null dihilangkan, begitu pula #text yang berisi null di samping elemen anak, karena XML hanya menyatakan null untuk elemen utuh.
  • Karakter yang sama sekali tidak dapat ditampung XML 1.0, bahkan sebagai referensi pun tidak, diganti, dan halaman ini mengatakan di mana.

Escape adalah bagian dari menulis XML yang well-formed, bukan pilihan. Tanda < dan tanda & selalu di-escape. Di dalam nilai atribut, kutip ganda juga di-escape, karena nilainya ditulis di antara dua kutip ganda; tab, line feed, atau carriage return di sana ditulis sebagai referensi karakter, karena jika tidak, pengurai akan mengubahnya menjadi spasi. Di dalam teks, carriage return ditulis sebagai referensi, karena jika tidak, pengurai akan mengubahnya menjadi line feed, dan ]]> tidak pernah ditulis apa adanya. Itulah yang membuat nilai terbaca kembali sebagai nilai yang Anda tulis.

Apa hasil konversi balik, dikatakan sebelum Anda mengonversi

Sebagian XML well-formed tetapi tetap terbaca kembali sebagai sesuatu yang berbeda dari JSON asalnya, jadi halaman ini membaca XML yang baru saja ditulisnya, dengan aturan yang sama yang dipakai arah sebaliknya, dan mengatakan di mana hasilnya berbeda. Larik berisi satu anggota terbaca kembali sebagai satu-satunya anggotanya, kecuali elemen yang sama berulang di bawah satu induk di tempat lain dalam dokumen. Larik kosong tidak menulis elemen apa pun dan #text kosong tidak menulis teks apa pun, jadi masing-masing tidak menghasilkan apa pun saat dibaca kembali. Objek yang tidak berisi apa pun yang ditulis sebagai atribut atau elemen anak terbaca kembali sebagai nilai biasa, dan di tempat elemen yang sama di bagian lain membuat dokumen memutuskan larik atau objek yang tidak dimiliki JSON Anda, hal itu juga dikatakan. Masing-masing ditulis sebagaimana adanya di JSON Anda, lalu diumumkan.

"Gunakan sebagai masukan" memindahkan keluaran ke panel masukan dan membalik arah, jadi apa yang kembali, dan apa yang diumumkannya, tinggal sekali klik. Di tempat tidak ada yang diumumkan, yang kembali adalah JSON Anda, selain apa yang tidak disimpan XML. Teks XML tidak mencatat apakah suatu nilai tadinya angka, boolean, atau string: dengan "Konversi angka dan boolean" menyala, string yang mengeja angka secara persis bisa kembali sebagai angka itu, dan dengan sakelar itu mati, setiap nilai kembali sebagai teks. Dan atribut, atau #text yang kosong atau null, bisa kembali di posisi yang berbeda di antara kunci-kunci di sampingnya, karena XML tidak menyimpan posisi itu.

Perjalanan bolak-balik dari sisi XML sengaja menjanjikan lebih sedikit. Teks yang Anda tempel tidak kembali: deklarasinya, tata letaknya, komentarnya, dan semua hal lain yang diumumkan pada perjalanan pergi hilang. Yang tetap stabil adalah XML yang ditulis halaman ini: konversikan ke JSON lalu kembali lagi, dengan pengaturan yang sama, dan XML yang sama akan kembali.

Ketika XML atau JSON tidak dapat dibaca

Dokumen yang tidak dapat dibaca pengurai XML ditolak dengan kalimat yang mengatakan apa yang salah, beserta baris dan kolom di mana pun ada tempat yang bisa ditunjukkan: elemen yang tidak pernah ditutup, nilai atribut tanpa kutip, dan tanda & yang tidak memulai referensi apa pun masing-masing punya kalimatnya sendiri. Tag penutup yang tidak cocok dengan elemen yang masih terbuka mengatakan hal itu, lalu menampilkan tag penutup yang dibutuhkan elemen tersebut, yang menyebut nama elemen yang dibiarkan terbuka. JSON yang tidak dapat diurai ditolak dengan cara yang sama, beserta baris dan kolom tempat pengurainya berhenti, di mana pun hal itu dapat diukur.

Di bawah kalimat yang menunjukkan tempat, halaman ini menampilkan baris Anda sendiri dengan karakter yang bermasalah disorot, yang paling penting untuk XML atau JSON yang diperkecil, tempat seluruh dokumen berada di satu baris. Baris yang panjang dipotong menjadi bagian di sekitar sorotan, dengan elipsis di tempat pemotongannya. Karakter bermasalah yang tidak menggambar apa pun, seperti akhir teks, tab, atau tanda urutan bita, disorot pada simbol terlihat yang mewakilinya. Kolom dihitung dengan cara JavaScript menghitung string, dalam unit kode UTF-16, jadi emoji atau ideogram langka sebelum sorotan memajukan kolomnya dua, bukan satu.

Dokumen yang bersarang lebih dalam daripada yang diizinkan situs ini juga ditolak, di arah mana pun, dan kalimatnya menyebutkan batasnya.

Pertanyaan yang sering diajukan

Mengapa elemen tunggal ditulis sebagai larik?
Karena elemen di jalur yang sama berulang di bawah satu induk di tempat lain dalam dokumen, dan jalur itu diputuskan satu kali untuk seluruh dokumen. Kode yang membaca nilai itu sebagai larik pun bekerja untuk setiap rekaman, termasuk rekaman dengan satu elemen. Halaman ini menyebut jalurnya, beserta baris dan kolom elemen pertama yang diubah oleh keputusan itu. Untuk mendapatkan larik di tempat sampel Anda hanya berisi satu, sebutkan elemen itu di "Selalu larik".
Mengapa ada angka yang dikutip di JSON saya?
Karena ada nilai di jalur yang sama yang tidak akan bertahan sebagai angka, entah karena nol di depan, nol di ujung setelah titik desimal, tanda plus, atau eksponen, atau karena angka dan boolean bertemu di jalur itu. Jalur seperti itu berupa teks di mana-mana, dan halaman ini menyebutnya. Nilai-nilainya dikonversi begitu setiap nilai ditulis sebagaimana angka itu ditulis kembali, 2134 dan bukan 02134.
Apa yang terjadi pada komentar, instruksi pemrosesan, dan DOCTYPE?
Semuanya tidak dimasukkan ke JSON, dan setiap jenis diumumkan beserta jumlahnya dan letak yang pertama. Pemberitahuan untuk DOCTYPE juga mengatakan bahwa DTD tidak diterapkan, jadi nilai bawaan atribut apa pun yang dideklarasikannya tidak ada.
Apakah alat ini memeriksa XML saya terhadap DTD atau XSD?
Tidak. Alat ini membaca XML yang well-formed dan mengatakan di mana ia tidak dapat membaca dokumen, tetapi tidak memvalidasi terhadap DTD atau XSD, dan tidak menerapkan apa pun yang dideklarasikan DTD. Itulah sebabnya DOCTYPE diumumkan sebagai tidak diterapkan, bukan diabaikan diam-diam.
Bagaimana null ditulis dalam XML, dan apakah ia kembali?
Sebagai elemen kosong yang ditandai xsi:nil="true", dengan ruang-nama XML Schema instance dideklarasikan satu kali pada elemen akar. Mengonversi XML itu kembali memberi null lagi, sedangkan elemen kosong biasa akan kembali sebagai string kosong di jalur mana pun yang dibaca sebagai teks. Jika JSON Anda sudah memakai prefiks xsi untuk salah satu namanya sendiri, halaman ini mendeklarasikan prefiks yang bebas sebagai gantinya.
Apa yang terjadi pada kunci yang mengandung spasi?
Kunci itu ditulis dengan nama terdekat yang diizinkan XML, jadi first name menjadi first_name, dan halaman ini menyebut kunci itu menurut JSONPath-nya beserta nama yang menjadi hasilnya. Tempel JSONPath itu ke Penguji JSONPath di situs ini untuk memilih setiap nilai yang terkena penulisan ulang itu.
Mengapa mengonversi kembali tidak memberi saya XML asli saya?
Karena JSON tidak punya tempat untuk sebagian isi berkas XML: deklarasi, tata letak di antara elemen, komentar, instruksi pemrosesan, DOCTYPE, dan urutan konten campuran. Yang membawa makna telah diumumkan pada perjalanan pergi. Yang tetap stabil adalah XML yang ditulis halaman ini: bawa ke JSON lalu kembali lagi, dengan pengaturan yang sama, dan XML yang sama akan kembali.
Apakah ada yang saya tempel dikirim ke server?
Tidak. Kedua arah berjalan sepenuhnya di peramban Anda, jadi dokumen yang Anda tempel, entah respons API, umpan, atau berkas konfigurasi yang berisi kredensial, tak pernah meninggalkan perangkat Anda.

Alat terkait

  • Pemformat JSON

    Validasi dan percantik JSON, dengan lokasi galat yang jelas.

  • Pemformat SQL

    Format dan percantik SQL — berbagai dialek.

  • Pemformat XML

    Format XML dan periksa apakah well-formed — percantik atau perkecil.

  • Konverter CSV ke JSON

    Ubah CSV ke JSON dan sebaliknya — pengutipan ditangani dengan benar.