Cara Menterjemah Fail Bahasa JSON Tanpa Merosakkan Kunci atau Pemegang Tempat
Lihat nilai mana dalam fail en.json yang diterjemahkan, apa yang ditulis semula oleh penterjemah fail (komen, susunan kunci, ID besar), dan cara menyemak pemegang tempat, plural ICU, dan kunci dengan skrip percuma dan fail ujian.

Untuk menterjemah fail bahasa JSON seperti en.json, berikan keseluruhan fail kepada penterjemah yang memahami JSON. Menampal teks mentah ke dalam tetingkap sembang atau penterjemah web adalah cara yang berisiko. Penterjemah yang memahami JSON membaca fail, menterjemah hanya nilai teks, dan menulis semula kunci yang sama, supaya aplikasi anda masih boleh memuatkan fail itu. Salin dan tampal boleh menterjemah kunci, menukar tanda petikan, atau menggugurkan pendakap. Mana-mana daripada itu merosakkan fail.
Mengekalkan kunci adalah bahagian yang mudah. Kebanyakan masalah datang selepas itu: pemegang tempat {name} yang kembali sebagai {nom}, plural ICU yang kehilangan kes other, URL yang dihantar untuk diterjemah seperti teks biasa, dan beberapa perubahan yang dibuat oleh penterjemah pada fail itu sendiri. Itulah yang diliputi oleh panduan ini.
Kami membina fail ujian dengan setiap satu daripada kes tersebut di dalamnya dan menulis penyemak percuma yang membandingkan fail sumber dengan terjemahannya. Kami juga menjalankan fail ujian itu melalui salinan tempatan kod penghuraian dan penulisan JSON yang digunakan oleh BookTranslator, dengan penanda sebagai ganti model, supaya anda dapat melihat dengan tepat nilai mana yang dihantar dan bagaimana fail itu kembali.
Jawapan Pantas: Apa yang Berlaku pada Setiap Bahagian Fail
| Bahagian fail | Contoh daripada ujian kami | Apa yang BookTranslator lakukan | Apa yang perlu disemak |
|---|---|---|---|
| Kunci | "greeting", "error" | Dikekalkan seperti sedia ada | Tiada |
| Nilai teks biasa | "Reading list" | Diterjemah | Makna, panjang pada skrin |
| Nilai dengan pemegang tempat | "Welcome back, {name}!", "Saved %s of %d chapters" | Diterjemah, pemegang tempat disertakan dalam teks yang dihantar | Nama dan kiraan pemegang tempat (penyemak melakukan ini) |
| Mesej plural ICU | "{count, plural, one {# book} other {# books}}" | Dihantar sebagai satu rentetan | Kes other, dan kategori plural untuk bahasa sasaran |
| HTML sebaris | "accept the <b>Terms</b>." | Diterjemah; kiraan tag disemak selepas terjemahan | Nama dan kiraan tag (pemeriksa melakukan ini) |
| URL disimpan sebagai teks | "https://example.com/help" | Dihantar untuk terjemahan | Bahawa ia kembali tanpa perubahan |
| Nilai tanpa huruf | "2.4.1", "—", "" | Dibiarkan seperti asal | Tiada |
Nombor, true/false, null | 20, true | Dibiarkan seperti asal | ID yang sangat besar (lihat di bawah) |
| Tatasusunan rentetan | ["Open", "Save", "Export as EPUB"] | Diterjemah dalam fail terjemahan; dibiarkan tidak diterjemah dalam fail dwibahasa | Fail dwibahasa, jika anda menggunakannya |
| Komen (JSONC) | // Shown on the home screen | Dibuang. Jika nilai juga mengandungi //, fail mungkin gagal dimuatkan | Buang komen sebelum muat naik |
Baki panduan ini menunjukkan dari mana setiap baris datang dan apa yang perlu dilakukan mengenainya.
Langkah 1: Semak Fail Sumber Sebelum Anda Muat Naik
Jalankan pemeriksa pada fail yang anda rancang untuk diterjemah. Ia memerlukan Python 3 dan tiada yang lain:
python3 check_i18n_json.py en.json
Pada fail ujian kami, ia mencetak:
WARN limits.projectId: 9007199254740993 is above 2^53 and can change in a JavaScript round trip; store IDs as strings
WARN error.network: a flat key with dots and a nested key resolve to the same dot path; tools that address strings by dot path can mix them up
INFO (root): 3 keys look like integers; JavaScript sorts those first and in numeric order when it rewrites the object
INFO source: 17 strings, 2 numbers
Dua amaran dan nota tentang kunci seperti integer itu masing-masing sepadan dengan perubahan yang kami lihat apabila fail ujian kami melalui penterjemah. Jika fail anda tidak mendapat sebarang amaran, anda boleh terus ke Langkah 3.
Pemeriksa juga menolak fail yang bukan JSON ketat, seperti yang mempunyai komen atau koma mengekor, kerana itu masalah seterusnya.
Apa Yang Kembali Daripada Fail Ujian Kami
Ujian dijalankan pada 2 November 2026, terhadap pengendalian JSON semasa dalam backend BookTranslator. Daripada memanggil model, ujian menggantikan setiap nilai yang akan dihantar untuk terjemahan dengan [ZH] ditambah teks asal. Ini menjadikan hasilnya boleh dijangka: apa-apa yang mempunyai [ZH] di hadapannya telah dihantar, apa-apa yang tiada tidak dihantar. Kedua-dua output diterbitkan: fail terjemahan dan fail dwibahasa.
Fail terjemahan
Setiap kunci dikembalikan tanpa perubahan, dan fail masih boleh dihuraikan. Nilai yang mengandungi huruf telah dihantar, termasuk {name}, %s, mesej ICU, tag <b>, dan URL bantuan. Rentetan versi "2.4.1", sengkang, dan rentetan kosong tidak dihantar kerana ia tidak mengandungi huruf. Nombor dan boolean dibiarkan begitu sahaja.
Empat perkara lain berubah:
- Satu rentetan masuk ke kunci yang salah. Dalam ujian kami, fail kami mempunyai kunci rata
"error.network"dengan teks "Check your connection." dan juga"error": { "network": "Network error" }yang bersarang. Penterjemah mengenal pasti setiap rentetan melalui laluannya dengan titik antara bahagian, jadi kedua-dua rentetan mempunyai alamat yang sama,error.network. Dalam output, kedua-dua kunci memegang terjemahan "Network error". "Check your connection." telah hilang. Ini memerlukan kedua-dua gaya dalam fail yang sama, yang jarang berlaku, tetapi ia gagal secara senyap. Pemeriksa memberi amaran tentangnya sebelum anda memuat naik. - Kunci seperti integer disusun semula.
"steps": { "10": ..., "2": ..., "1": ... }dikembalikan sebagai"1","2","10". JavaScript sentiasa menyenaraikan kunci seperti integer dahulu, dalam susunan berangka, apabila ia membina semula objek. Kunci dan nilai masih sepadan, jadi aplikasi anda tidak terjejas, tetapi perbezaan berbanding fail sumber akan menjadi bising. - ID besar kehilangan ketepatan.
9007199254740993dikembalikan sebagai9007199254740992. JavaScript menyimpan nombor sebagai titik terapung 64-bit, dan integer melebihi 2^53 tidak semuanya boleh diwakili dengan tepat (MDN tentangNumber.MAX_SAFE_INTEGER). Simpan ID panjang sebagai rentetan, atau jauhkan ia daripada fail bahasa. - Pemformatan ditulis semula. Output menggunakan indentasi dua ruang dan berakhir dengan baris baharu. Jika sumber anda menggunakan tab atau empat ruang, jangkakan perubahan ruang putih dalam perbezaan.
Fail ujian kami tidak mempunyai kunci pendua, tetapi ia wajar diketahui: penghurai JSON JavaScript hanya menyimpan nilai terakhir untuk kunci berulang, jadi teks terdahulu tidak pernah diterjemah. Aplikasi anda akan memuatkan nilai terakhir yang sama, jadi tiada yang kelihatan rosak, tetapi pemeriksa menyenaraikan kunci pendua supaya anda boleh membersihkannya.
Fail dwibahasa
Fail dwibahasa mengekalkan setiap nilai asal dan menambah kunci bersaudara dengan _translated di hujungnya:
"greeting": "Welcome back, {name}!",
"greeting_translated": "[ZH] Welcome back, {name}!",
Itu berfungsi dengan baik untuk semakan, kerana sumber dan terjemahan terletak bersebelahan. Ia bukan fail yang boleh dimuatkan oleh aplikasi anda, kerana setiap kunci kini mempunyai kembar. Gunakan fail terjemahan dalam aplikasi anda.
Satu jurang: rentetan dalam tatasusunan tidak mendapat _translated bersaudara, kerana item tatasusunan tiada kunci untuk ditambah. Dalam ujian kami, "menu": ["Open", "Save", "Export as EPUB"] dikembalikan dalam bahasa Inggeris dalam fail dwibahasa, tetapi diterjemah dalam fail terjemahan. Jika anda menyemak daripada fail dwibahasa, semak tatasusunan dalam fail terjemahan.
Fail dengan komen
Banyak projek menyimpan komen dalam fail bahasa mereka (JSONC), yang tidak dibenarkan oleh JSON ketat. Penterjemah mula-mula mencuba JSON ketat. Jika gagal, ia membuang komen dan koma mengekor dan mencuba lagi. Membuang komen bermaksud memadam segala-galanya selepas // pada satu baris, dan itu termasuk // dalam https://.
Fail kami dengan komen dan URL tidak dimuatkan langsung; penghuraian gagal pada komen pertama. Fail dengan komen tetapi tiada // dalam mana-mana nilai dimuatkan dengan baik, dan komen dibuang daripada output.
Jadi: jika fail anda mempunyai komen, buangnya sebelum anda memuat naik, atau simpan salinan dengan komen dan terima bahawa terjemahan tidak akan memilikinya.
Langkah 2: Sediakan Fail
Anda boleh membetulkan kebanyakan masalah ini sebelum anda menterjemah:
- Jadikan ia JSON ketat. Buang komen dan koma mengekor. Jika alat binaan anda membaca JSONC, simpan fail berkomen sebagai sumber anda dan eksport salinan bersih untuk terjemahan.
- Gunakan satu gaya kunci. Sama ada sarangkan kunci atau ratakan dengan titik, bukan kedua-duanya dalam satu fail. Jika anda menggunakan i18next, pilihan
keySeparatormengawal cara titik dalam kunci dibaca, jadi semak tetapan itu sebelum anda meratakan apa-apa. - Pindahkan data bukan teks keluar. ID, URL, bendera ciri, dan had tergolong dalam konfigurasi, bukan dalam fail bahasa. Jika URL mesti kekal, kekalkan ia, tetapi jangkakan untuk menyemaknya selepas terjemahan. Panduan jangan-terjemah kami merangkumi cara memutuskan apa lagi yang patut kekal dalam bahasa asal.
- Tulis pemegang tempat dengan cara yang sama di mana-mana. Satu gaya, seperti
{name}, lebih mudah disemak daripada campuran{name},{{name}}, dan%s.
Langkah 3: Terjemah Seluruh Fail
Muat naik fail yang telah dibersihkan ke penterjemah dokumen BookTranslator, yang menyenaraikan .json bersama format penyetempatan dan teks berstruktur lain yang diterimanya. Harga ditunjukkan sebelum pembayaran. Apabila tugas selesai, halaman sejarah anda menawarkan fail terjemahan dan fail dwibahasa sebagai muat turun berasingan.
Dua perkara tentang cara teks diterjemahkan mempengaruhi hasilnya:
- Model tidak melihat kunci anda. Setiap nilai dihantar sebagai segmen bernombor, tanpa nama kunci. Jika
"button.open"dan"status.open"kedua-duanya menyatakan "Open", model tidak dapat mengetahui bahawa satu ialah kata kerja dan satu lagi ialah kata sifat. Rentetan pendek yang kabur ialah yang perlu disemak secara manual. - Setiap nilai diterjemahkan secara berasingan. Tiada apa yang mengaitkan dua kunci bersama, jadi perkataan yang sama di dua tempat boleh kembali dalam dua cara berbeza, dan perkataan yang memerlukan dua terjemahan berbeza boleh kembali sama. Glosari auto pilihan BookTranslator mengumpul nama, tempat, dan istilah khusus serta mengekalkannya konsisten, tetapi anda tidak boleh memberikannya terjemahan tetap anda sendiri. Untuk istilah yang mesti diterjemahkan dengan satu cara tepat, simpan senarai istilah dan semak rentetan tersebut selepas terjemahan; panduan glosari kami menerangkan cara merancangnya.
Tag HTML sebaris dikira selepas terjemahan, dan segmen yang tagnya tidak sepadan akan dicuba semula. Placeholder kurungan kerinting, placeholder gaya %s, dan sintaks ICU dihantar sebagai sebahagian daripada teks tetapi tidak disemak dengan cara yang sama. Jalankan Langkah 4 pada setiap terjemahan.
Jika anda lebih suka menterjemah dengan model sembang atau model setempat, hantar nilai sahaja, jangan sekali-kali fail mentah, dan letakkan semula mengikut kunci dengan skrip. Semakan di bawah terpakai sama ada cara.
Langkah 4: Semak Fail Terjemahan
Bandingkan terjemahan dengan sumber:
python3 check_i18n_json.py en.json fr.json
Untuk menunjukkan apa yang ia tangkap, kami membuat fail Perancis dengan ralat yang ditanam. Ia dibuat secara manual, bukan output model. Selepas amaran sumber yang sama seperti dalam Langkah 1, penyemak mencetak:
ERROR app.greeting: placeholders differ; lost ['name'] extra ['nom']
ERROR app.help_url: urls differ; lost ['https://example.com/help'] extra ['https://example.com/aide']
ERROR app.items: ICU message has no 'other' case
ERROR app.legacy: placeholders differ; lost ['%d'] extra []
ERROR limits.maxFiles: type changed from int to str
ERROR limits.projectId: non-text value changed: 9007199254740993 -> 9007199254740992
INFO menu[1]: identical to source: 'Save'
INFO compared 20 source values, 1 unchanged strings
Setiap satu daripadanya akan muncul sebagai pepijat dalam aplikasi: nama kosong, pautan rosak, ranap atau mesej mentah apabila bentuk jamak dipaparkan, kiraan bab yang hilang, had yang dibandingkan sebagai teks. Baris INFO menyenaraikan rentetan yang kembali tidak berubah. Sesetengahnya tidak mengapa, seperti nama jenama; "Save" dalam menu Perancis tidak.
Penyemak membandingkan kunci, jenis nilai, nilai bukan teks, placeholder ({name}, {{name}}, %s, %1$s, %@), nama argumen ICU, tag HTML, dan URL. Ia tidak menilai terjemahan itu sendiri.
Kes jamak memang sepatutnya berubah
Jamak ICU menyenaraikan satu mesej bagi setiap kategori jamak. Bahasa Inggeris mempunyai dua kategori, one dan other, tetapi banyak bahasa mempunyai set yang berbeza. Terjemahan Rusia yang baik bagi mesej items kami biasanya akan menggunakan one, few, many, dan other, dan terjemahan Jepun hanya other. Jadi ketidakpadanan di sini bukan selalu ralat.
Kategori ini datang daripada peraturan jamak Unicode CLDR, dan other ialah yang ada dalam setiap bahasa. Ini ialah kategori kardinal yang dilaporkan oleh Intl.PluralRules dalam Node.js dengan CLDR 48:
| Bahasa | Kategori jamak |
|---|---|
| Bahasa Inggeris, Jerman | one, other |
| Perancis, Sepanyol, Portugis | one, many, other |
| Rusia, Poland | one, few, many, other |
| Arab | zero, one, two, few, many, other |
| Jepun, Cina, Korea | lain |
Bahasa Perancis, Sepanyol dan Portugis menggunakan many hanya untuk nombor bulat yang sangat besar, seperti sejuta, jadi mesej untuk kiraan kecil biasanya tidak memerlukannya. Pemeriksa melaporkan other yang hilang sebagai ralat, dan sebarang perubahan lain dalam kategori sebagai amaran untuk dibandingkan dengan jadual ini. Anda boleh mencetak senarai untuk mana-mana bahasa sendiri:
node -e 'console.log(new Intl.PluralRules("ru").resolvedOptions().pluralCategories)'
Penterjemah diberikan kes bahasa Inggeris, jadi semak apa yang dikembalikan. Jika mesej bahasa Rusia atau Arab masih hanya mempunyai one dan other, tambah kes yang hilang secara manual, atau minta penterjemah melakukannya.
Kemudian muatkannya dalam aplikasi
Pemeriksa membuktikan fail itu selamat dimuatkan, bukan bahawa ia mudah dibaca. Tukar aplikasi kepada bahasa baharu dan lihat skrin: perkataan panjang dalam bahasa Jerman atau Finland yang melimpah keluar butang, teks kanan-ke-kiri dalam bahasa Arab atau Ibrani, dan tarikh atau nombor yang kod anda format secara berasingan daripada fail bahasa. Panduan kami tentang terjemahan berbanding penyetempatan merangkumi perkara lain yang berubah antara pasaran selain perkataan.
Masalah Lazim
Fail terjemahan tidak akan dimuatkan dalam aplikasi saya. Jalankan pemeriksa ke atasnya. Jika pemeriksa tidak dapat menghuraikannya, fail itu telah diedit selepas terjemahan atau memang tidak sah sejak awal. Jika ia berjaya dihuraikan, cari baris ERROR tentang kunci atau jenis.
Sesuatu rentetan muncul sebagai mesej ICU mentah, seperti {count, plural, ...}. Sintaks ICU rosak semasa terjemahan, biasanya pendakap yang hilang atau kes other yang hilang. Salin struktur daripada sumber dan terjemahkan hanya perkataan di dalam setiap kes.
Fail saya ialah YAML, fail .po, atau Markdown. BookTranslator juga menerima format tersebut, tetapi setiap format mempunyai peraturannya sendiri. Untuk dokumentasi, lihat panduan terjemahan Markdown kami; untuk halaman web, lihat panduan fail HTML.
Bolehkah saya terjemahkan hanya kunci baharu? Tidak dalam satu muat naik; keseluruhan fail diterjemahkan. Letakkan kunci baharu dalam fail berasingan, terjemahkannya, dan gabungkan hasilnya mengikut kunci. Pemeriksa akan mengesahkan fail yang digabungkan mempunyai setiap kunci.
Patutkah saya terjemahkan kunci? Tidak. Kunci ialah pengecam yang dicari oleh kod anda. Hanya nilai ialah teks untuk dibaca oleh orang.
Catatan Berkaitan





