BookTranslator
BookTranslator

Hogyan fordítsunk le egy JSON nyelvi fájlt a kulcsok és helyőrzők törése nélkül

Nézze meg, mely értékek fordulnak le egy en.json fájlban, mit ír át egy fájlfordító (megjegyzések, kulcssorrend, nagy azonosítók), és hogyan ellenőrizheti a helyőrzőket, az ICU többes számokat és a kulcsokat egy ingyenes szkripttel és egy tesztfájllal.

BookTranslator

BookTranslator Team

12 perc olvasás

Egy JSON nyelvi fájl, például az en.json lefordításához adja át a teljes fájlt egy JSON-t értő fordítónak. A nyers szöveg beillesztése egy csevegőablakba vagy egy webes fordítóba kockázatos módszer. A JSON-t értő fordító beolvassa a fájlt, csak a szöveges értékeket fordítja le, és ugyanazokat a kulcsokat írja vissza, így az alkalmazása továbbra is be tudja tölteni a fájlt. A másolás és beillesztés lefordíthat egy kulcsot, megváltoztathat egy idézőjelet vagy elhagyhat egy kapcsos zárójelet. Ezek bármelyike tönkreteszi a fájlt.

A kulcsok megtartása a könnyű rész. A legtöbb probléma utána jön: egy {name} helyőrző, amely {nom}-ként tér vissza, egy ICU többes szám, amely elveszíti az other esetét, egy URL, amelyet a rendszer a többi szöveghez hasonlóan fordításra küld, és néhány változtatás, amelyet a fordító magán a fájlon tesz. Ezeket tárgyalja ez az útmutató.

Készítettünk egy tesztfájlt, amelyben minden ilyen eset szerepel, és írtunk egy ingyenes ellenőrzőt, amely összehasonlítja a forrásfájlt a fordításával. A tesztfájlt lefuttattuk a BookTranslator által használt JSON-elemző és -író kód helyi példányán is, a modell helyén egy jelölővel, így pontosan láthatja, mely értékek kerülnek elküldésre, és hogyan jön vissza a fájl.

Rövid válasz: Mi történik a fájl egyes részeivel

A fájl részePélda a tesztünkbőlMit tesz a BookTranslatorMit kell ellenőrizni
Kulcsok"greeting", "error"Változatlanul maradnakSemmit
Egyszerű szöveges értékek"Reading list"LefordítvaJelentés, hosszúság a képernyőn
Helyőrzőket tartalmazó értékek"Welcome back, {name}!", "Saved %s of %d chapters"Lefordítva, a helyőrzők az elküldött szövegben szerepelnekHelyőrzők nevei és száma (az ellenőrző végzi el)
ICU többes számú üzenetek"{count, plural, one {# book} other {# books}}"Egyetlen karakterláncként elküldveAz other eset és a célnyelv többes számú kategóriái
Beágyazott HTML"accept the <b>Terms</b>."Lefordítva; a címkék számát a fordítás után ellenőrziCímkenevek és darabszámok (ezt végzi a checker)
Szövegként tárolt URL-ek"https://example.com/help"Fordításra elküldveHogy változatlanul jött vissza
Értékek betűk nélkül"2.4.1", "—", ""Változatlanul hagyvaSemmi
Számok, true/false, null20, trueVáltozatlanul hagyvaNagyon nagy ID-k (lásd alább)
Sztringekből álló tömbök["Open", "Save", "Export as EPUB"]A lefordított fájlban lefordítva; a kétnyelvű fájlban fordítás nélkül hagyvaA kétnyelvű fájl, ha használod
Megjegyzések (JSONC)// Shown on the home screenEltávolítva. Ha egy érték is tartalmaz //-t, a fájl betöltése meghiúsulhatTávolítsd el a megjegyzéseket feltöltés előtt

Az útmutató további része bemutatja, honnan származik az egyes sorok tartalma, és mit érdemes tenni velük.

1. lépés: Ellenőrizd a forrásfájlt feltöltés előtt

Futtasd a checkert a lefordítani kívánt fájlon. Csak Python 3-ra van szükség, semmi másra:

python3 check_i18n_json.py en.json

A tesztfájlunkon ezt írta ki:

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

A két figyelmeztetés és az egész számra hasonlító kulcsokra vonatkozó megjegyzés mind olyan változásnak felel meg, amelyet akkor tapasztaltunk, amikor a tesztfájlunk átment a fordítón. Ha a fájlod egyiket sem kapja, ugorhatsz a 3. lépésre.

A checker továbbá elutasítja azokat a fájlokat, amelyek nem szigorú JSON-t tartalmaznak, például megjegyzéseket vagy záró vesszőket, mert ez a következő probléma.

Mi jött vissza a tesztfájlunkból

A teszt 2026. november 2-án futott a BookTranslator backendjének aktuális JSON-kezelésével. Modellhívás helyett a teszt minden fordításra küldendő értéket [ZH] előtaggal és az eredeti szöveggel helyettesített. Így az eredmény kiszámítható marad: ami előtt [ZH] állt, azt elküldték, ami előtt nem, azt nem. Mindkét kimenet közzétéve: a lefordított fájl és a kétnyelvű fájl.

A lefordított fájl

Minden kulcs változatlanul került vissza, és a fájl továbbra is beolvasható volt. A betűket tartalmazó értékeket elküldtük, köztük a {name}, a %s, az ICU üzenet, a <b> tag és a súgó URL-jét. A "2.4.1" verziószámot, a kötőjelet és az üres karakterláncot nem küldtük el, mert nem tartalmaznak betűket. A számokat és a logikai értékeket érintetlenül hagytuk.

Négy másik dolog megváltozott:

  1. Egy karakterlánc rossz kulcsba került. A tesztünkben a fájlunkban volt egy lapos "error.network" kulcs a "Check your connection." szöveggel, valamint egy beágyazott "error": { "network": "Network error" } is. A fordító minden karakterláncot a részek közötti pontokkal jelölt útvonala alapján azonosít, így mindkét karakterlánc ugyanazt a címet kapta: error.network. A kimenetben mindkét kulcs a "Network error" fordítását tartalmazta. A "Check your connection." eltűnt. Ehhez mindkét stílusnak ugyanabban a fájlban kell lennie, ami ritka, de csendben meghiúsul. Az ellenőrző figyelmeztet rá a feltöltés előtt.
  2. Az egész számra hasonlító kulcsok átrendeződtek. A "steps": { "10": ..., "2": ..., "1": ... } eredménye "1", "2", "10" lett. A JavaScript mindig először az egész számra hasonlító kulcsokat listázza numerikus sorrendben, amikor újraépít egy objektumot. A kulcsok és értékek továbbra is összetartoznak, így az alkalmazásod rendben van, de a forrásfájlhoz viszonyított diff zajos lesz.
  3. Egy nagy ID elvesztette a pontosságát. A 9007199254740993 eredménye 9007199254740992 lett. A JavaScript a számokat 64 bites lebegőpontosként tárolja, és a 2^53 feletti egészek nem mindegyike ábrázolható pontosan (MDN a Number.MAX_SAFE_INTEGER-ről). A hosszú ID-ket tárold karakterláncként, vagy tartsd távol őket a nyelvi fájltól.
  4. A formázás újraíródott. A kimenet két szóköz behúzást használ, és újsorral végződik. Ha a forrásod tabulátorokat vagy négy szóközt használt, számíts szóközbeli változásokra a diffben.

A tesztfájlunkban nem voltak ismétlődő kulcsok, de érdemes tudni róluk: a JavaScript JSON-elemzője egy ismétlődő kulcs esetén csak az utolsó értéket tartja meg, így a korábbi szöveg soha nem kerül lefordításra. Az alkalmazásod ugyanazt az utolsó értéket töltené be, így semmi látható nem törik el, de az ellenőrző felsorolja az ismétlődő kulcsokat, hogy kitakaríthasd őket.

A kétnyelvű fájl

A kétnyelvű fájl megtartja az eredeti értékeket, és hozzáad egy testvérkulcsot a végén _translated utótaggal:

"greeting": "Welcome back, {name}!",
"greeting_translated": "[ZH] Welcome back, {name}!",

Ez jól működik ellenőrzéshez, mert a forrás és a fordítás egymás mellett van. Ez nem egy fájl, amelyet az alkalmazásod be tud tölteni, mert most minden kulcsnak van ikertestvére. Az alkalmazásodban a lefordított fájlt használd.

Egy hiányosság: a tömbökön belüli karakterláncok nem kapnak _translated testvért, mert a tömb elemeinek nincs kulcsuk, amihez hozzá lehetne adni. A tesztünkben a "menu": ["Open", "Save", "Export as EPUB"] angolul került vissza a kétnyelvű fájlban, de lefordítva a lefordított fájlban. Ha a kétnyelvű fájlból ellenőrzöl, nézd meg a tömböket a lefordított fájlban.

Megjegyzéseket tartalmazó fájlok

Sok projekt megjegyzéseket tart a nyelvi fájljaiban (JSONC), amit a szigorú JSON nem engedélyez. A fordító először szigorú JSON-t próbál. Ha ez nem sikerül, eltávolítja a megjegyzéseket és a záró vesszőket, majd újra próbálja. A megjegyzések eltávolítása azt jelenti, hogy egy sorban mindent töröl a // után, és ez magában foglalja a https://-ben lévő //-t is.

A megjegyzést és URL-t tartalmazó fájlunk egyáltalán nem töltődött be; az elemzés az első megjegyzésnél meghiúsult. Egy megjegyzéseket tartalmazó, de egyetlen értékben sem //-t tartalmazó fájl rendben betöltődött, és a megjegyzések eltűntek a kimenetből.

Tehát: ha a fájlodban vannak megjegyzések, távolítsd el őket a feltöltés előtt, vagy tarts meg egy másolatot a megjegyzésekkel, és fogadd el, hogy a fordításban nem lesznek benne.

2. lépés: A fájl előkészítése

A legtöbb ilyen problémát a fordítás előtt kijavíthatod:

  • Tedd szigorú JSON-ná. Távolítsd el a megjegyzéseket és a záró vesszőket. Ha a build eszközöd JSONC-t olvas, tartsd meg a megjegyzéseket tartalmazó fájlt forrásként, és exportálj egy tiszta másolatot a fordításhoz.
  • Használj egyetlen kulcsstílust. Vagy ágyazd a kulcsokat, vagy lapítsd őket pontokkal, de ne mindkettőt egy fájlban. Ha i18next-et használsz, a keySeparator opciója szabályozza, hogyan olvasódnak a kulcsokban lévő pontok, ezért ellenőrizd ezt a beállítást, mielőtt bármit lapítanál.
  • Vidd ki a nem szöveges adatokat. Az ID-k, URL-ek, funkciókapcsolók és limitek a konfigurációba tartoznak, nem a nyelvi fájlba. Ha egy URL-nek maradnia kell, tartsd meg, de számíts rá, hogy fordítás után ellenőrizni kell. A mit ne fordítsunk útmutatónk lefedi, hogyan döntsd el, mi más maradjon az eredeti nyelven.
  • Mindenhol ugyanúgy írd a helyőrzőket. Egyetlen stílus, például a {name}, könnyebben ellenőrizhető, mint a {name}, {{name}} és %s keveréke.

3. lépés: A teljes fájl lefordítása

Töltsd fel a megtisztított fájlt a BookTranslator dokumentumfordítójába, amely a .json-t a többi elfogadott lokalizációs és strukturált szövegformátum mellett listázza. Az ár a fizetés előtt látható. Amikor a feladat befejeződik, az előzmények oldalad külön letöltésként kínálja a lefordított fájlt és a kétnyelvű fájlt.

A szöveg fordításának két jellemzője befolyásolja az eredményt:

  • A modell nem látja a kulcsaidat. Minden érték egy sorszámozott szegmensként kerül elküldésre, a kulcs neve nélkül. Ha a "button.open" és a "status.open" is azt mondja, hogy „Open”, a modell semmiképpen nem tudhatja, hogy az egyik ige, a másik pedig melléknév. A rövid, kétértelmű karakterláncokat érdemes kézzel ellenőrizni.
  • Minden érték külön kerül lefordításra. Semmi sem kapcsolja össze a két kulcsot, így ugyanaz a szó két helyen két különböző formában is visszajöhet, és egy szó, amelynek két különböző fordítása szükséges, ugyanúgy is visszajöhet. A BookTranslator opcionális automatikus szójegyzéke összegyűjti a neveket, helyeket és szakszavakat, és konzisztensen tartja őket, de nem adhatsz meg saját rögzített fordításokat. Azoknál a kifejezéseknél, amelyeket pontosan egyféleképpen kell lefordítani, tartson egy kifejezéslistát, és a fordítás után ellenőrizze azokat a karakterláncokat; a szójegyzék-útmutatónk elmagyarázza, hogyan tervezzen egyet.

A beágyazott HTML-címkéket a fordítás után számolja a rendszer, és azokat a szegmenseket, amelyek címkéi nem egyeznek, újrapróbálja. A kapcsos zárójeles helyőrzőket, a %s-stílusú helyőrzőket és az ICU szintaxist a szöveg részeként küldi el, de nem ellenőrzi ugyanúgy. Futtassa a 4. lépést minden fordításnál.

Ha inkább csevegőmodellel vagy helyi modellel szeretne fordítani, csak az értékeket küldje el, soha ne a nyers fájlt, és egy szkripttel tegye vissza őket kulcs szerint. Az alábbi ellenőrzések mindkét esetben érvényesek.

4. lépés: A lefordított fájl ellenőrzése

Hasonlítsa össze a fordítást a forrással:

python3 check_i18n_json.py en.json fr.json

Hogy megmutassuk, mit fog el, készítettünk egy hibákkal tűzdelt francia fájlt. Ez kézzel készült, nem modellkimenet. Miután ugyanazokat a forrásfigyelmeztetéseket kapta, mint az 1. lépésben, az ellenőrző ezt írta ki:

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

Mindegyik hiba formájában jelenne meg az alkalmazásban: üres név, törött hivatkozás, összeomlás vagy nyers üzenet a többes szám megjelenítésekor, hiányzó fejezetszám, szövegként összehasonlított korlát. Az INFO sor a változatlanul visszajött karakterláncokat listázza. Néhány rendben van, például a márkanevek; a „Save” egy francia menüben nem az.

Az ellenőrző összehasonlítja a kulcsokat, az értéktípusokat, a nem szöveges értékeket, a helyőrzőket ({name}, {{name}}, %s, %1$s, %@), az ICU argumentumneveket, a HTML-címkéket és az URL-eket. Magát a fordítást nem bírálja el.

A többes számú eseteknek változniuk kell

Egy ICU többes számú üzenet többes számú kategóriánként egy üzenetet sorol fel. Az angolban két kategória van, one és other, de sok nyelvben más a készlet. Az items üzenetünk jó orosz fordítása általában one, few, many és other kategóriákat használna, a japán pedig csak other-t. Tehát az itteni eltérés nem mindig hiba.

A kategóriák a Unicode CLDR többes számú szabályaiból származnak, és az other az, amely minden nyelvben megvan. Ezek a Node.js Intl.PluralRules által a CLDR 48-cal jelentett kardinális kategóriák:

NyelvTöbbes számú kategóriák
Angol, németone, other
Francia, spanyol, portugálone, many, other
Orosz, lengyelone, few, many, other
Arabzero, one, two, few, many, other
Japán, kínai, koreaiegyéb

A francia, spanyol és portugál csak nagyon nagy kerek számoknál, például egymilliónál használja a many kategóriát, így a kis számokhoz tartozó üzeneteknél általában nincs rá szükség. Az ellenőrző a hiányzó other kategóriát hibaként jelzi, minden más kategóriaváltozást pedig figyelmeztetésként, amelyet ezzel a táblázattal kell összevetni. Bármely nyelv listáját maga is kinyomtathatja:

node -e 'console.log(new Intl.PluralRules("ru").resolvedOptions().pluralCategories)'

A fordító az angol eseteket kapja meg, ezért ellenőrizze, mi jött vissza. Ha egy orosz vagy arab üzenetben még mindig csak one és other szerepel, adja hozzá kézzel a hiányzó eseteket, vagy végeztesse el ezt a fordítóval.

Ezután töltse be az alkalmazásba

Az ellenőrző azt bizonyítja, hogy a fájl biztonságosan betölthető, nem azt, hogy jól olvasható. Váltson át az alkalmazásban az új nyelvre, és nézze meg a képernyőket: a német vagy finn hosszú szavakat, amelyek túlcsordulnak a gombokon, az arab vagy héber jobbról balra írt szöveget, valamint a dátumokat és számokat, amelyeket a kódja a nyelvi fájltól külön formáz. A fordítás és lokalizáció közötti különbségekről szóló útmutatónk bemutatja, mi változik még a szavakon kívül a piacok között.

Gyakori problémák

A lefordított fájl nem töltődik be az alkalmazásomban. Futtassa rajta az ellenőrzőt. Ha az ellenőrző nem tudja feldolgozni, a fájlt a fordítás után szerkesztették, vagy eleve érvénytelen volt. Ha feldolgozható, keressen ERROR sorokat a kulcsokkal vagy típusokkal kapcsolatban.

Egy karakterlánc nyers ICU-üzenetként, például {count, plural, ...} formában jelenik meg. A fordítás során megsérült az ICU-szintaxis, általában hiányzó kapcsos zárójel vagy hiányzó other eset miatt. Másolja át a szerkezetet a forrásból, és csak az egyes eseteken belüli szavakat fordítsa le.

A fájlom YAML, .po fájl vagy Markdown. A BookTranslator ezeket is elfogadja, de minden formátumnak megvannak a maga szabályai. Dokumentációhoz lásd a Markdown-fordítási útmutatónkat; weboldalakhoz a HTML-fájl útmutatót.

Csak az új kulcsokat fordíthatom le? Egyetlen feltöltésen belül nem; a teljes fájl lefordításra kerül. Tegye az új kulcsokat egy külön fájlba, fordítsa le, majd egyesítse az eredményt kulcs szerint. Az ellenőrző megerősíti, hogy az egyesített fájl minden kulcsot tartalmaz.

Le kell fordítanom a kulcsokat? Nem. A kulcsok azonosítók, amelyeket a kódja keres fel. Csak az értékek az emberek számára olvasható szövegek.

Kapcsolódó bejegyzések