Wat een .xlf-bestand is, en hoe je het opent
XLIFF is het XML Localisation Interchange File Format, een OASIS-standaard, en het komt binnen als een .xlf- of .xliff-bestand. Het is wat een ontwikkelaar aan een vertaler geeft: één regel per bericht, elk met de originele tekst en een plek voor de vertaalde tekst, plus wat de tool die het maakte verder wil onthouden. Angular, .NET, iOS, Symfony en elke serieuze CAT-tool lezen en schrijven het, en daarom belandt het in de inbox van iemand die er nog nooit van gehoord heeft.
Het is XML, dus elke teksteditor laat het bestand zien. Dat is zelden wat je wilt: de woorden die je zoekt staan tussen tags, verpakt in placeholders, drie niveaus diep. Zet het bestand op deze pagina neer en het opent in plaats daarvan als een lijst, één regel per bericht, origineel naast vertaling. Er wordt niets geïnstalleerd, er wordt niets geüpload, en het bestand wordt door je eigen browser gelezen.
Lezen en bewerken zijn hier hetzelfde scherm. Als viewer open je het bestand, loop je de regels langs, filter je op wat nog onvertaald is, en sluit je het tabblad: er wordt niets weggeschreven tenzij je downloadt. Als editor typ je in de kolom Vertaling en download je het bestand als je klaar bent. De rest van deze pagina gaat over wat er bij dat downloaden gebeurt, want daar beschadigt een XLIFF-tool meestal een bestand.
Wat deze editor verandert, en wat hij met rust laat
Je bestand wordt één keer geparst en als geparst document bewaard. Bij het downloaden worden alleen de <target>-elementen teruggeschreven die je echt hebt bewerkt, en wordt datzelfde document opnieuw geserialiseerd. Commentaar, notities, <context-group>-blokken, toolmetadata, inspringing en elementen waar deze editor nog nooit van gehoord heeft staan er allemaal nog, want er is nooit iets langs geweest.
Een paar dingen verschuiven wel, en die zitten allemaal in de XML-laag en niet in deze pagina. Een namespacedeclaratie wordt voor de andere attributen van het element geschreven, dus <xliff version="1.2" xmlns="…"> kan met die twee omgedraaid terugkomen. Een attribuut dat deze editor zelf zet, zoals target-language, komt achter de attributen die er al stonden. En een regeleinde binnen een attribuutwaarde komt terug als spatie: XML 1.0 §3.3.3 verplicht elke conforme parser dat zo te normaliseren, dus het document dat ingelezen werd had die newline echt nooit. Angular maakt die in de equiv-text-hint van een placeholder die uit een template tag over meerdere regels komt.
Het document wegschrijven normaliseert nog zeven dingen, en een diff laat ze allemaal zien. CRLF-regeleinden worden LF. Een leeg element verliest zijn sluittag, dus <target></target> komt terug als <target/>. Een character reference wordt geschreven als het teken dat hij benoemt, dus ' wordt een apostrof. Attribuutwaarden tussen enkele aanhalingstekens krijgen dubbele. Een UTF-8 byte order mark verdwijnt. Het bestand eindigt met een newline. En een processing instruction voor het rootelement, bijvoorbeeld een <?xml-stylesheet?>, houdt zijn eigen tekst maar verliest het regeleinde erna, en komt dus op dezelfde regel als <xliff> terecht. Niets daarvan verandert een waarde, een id of een bericht, maar als jouw repository .xlf-bestanden met CRLF-regeleinden bewaart, leest het hele bestand als herschreven, dus commit de download apart. Al het andere in een diff tegen het origineel is een vertaling die jij hebt geschreven.
Eenheden zonder <target>, en dat is elke eenheid van een net geëxtraheerd bestand, krijgen er een achter de bron, met de inspringing van het bestand zelf. De doeltaal wordt geschreven naar target-language op elke <file> in XLIFF 1.2 en naar trgLang op de root in 2.0.
Waarom er markup in het vertaalvak staat
Een bericht is zelden platte tekst. Angular schrijft <x id="INTERPOLATION"/> waar een expressie hoort en <x id="START_BOLD_TEXT"/> waar een tag opent; XLIFF 2.0 schrijft datzelfde als <ph/> en <pc>. Dat is geen versiering. Het zijn de gaten die de draaiende applicatie vult, en een vertaling die er een kwijtraakt is een vertaling die niet compileert.
De vertaling wordt daarom bewerkt als de XML die het werkelijk is, en de placeholders uit de bron worden als knoppen aangeboden die de originele tag letterlijk invoegen, met attributen en al. Elke eenheid wordt onder het typen gecontroleerd: een vertaling waarvan de placeholders niet bij de bron passen wordt gemarkeerd, en een vertaling die niet meer welgevormd is ook. Het filter Problemen verzamelt ze.
XLIFF 1.2 en 2.0
Allebei worden ze gelezen en geschreven. Ze schelen meer dan een versienummer: 1.2 houdt de tekst in <trans-unit> en markeert de voortgang met state op de vertaling, van new via needs-translation naar translated, signed-off en final. 2.0 pakt alles in een <segment> en houdt de status daar, met een kortere woordenlijst: initial, translated, reviewed, final. De statuskiezer toont de set die jouw bestand echt toestaat, en de waarde wordt geschreven waar die versie hem bewaart.
XLIFF 2.1 en 2.2 openen als 2.0. Het zijn aanvullende herzieningen met dezelfde structuur van eenheden en extra optionele modules, waar deze editor er geen van aanraakt.
Een nieuwe extractie vullen uit een oude vertaling
De gebruikelijke klus na het toevoegen van een feature: messages.xlf is opnieuw geëxtraheerd en heeft geen vertalingen, en de messages.nl.xlf van de vorige release heeft er honderden. Open het nieuwe bestand, laad het oude met Vergelijken met, en Lege vertalingen invullen kopieert elke vertaling over op id.
Eenheden waarvan de brontekst veranderd is worden overgeslagen in plaats van gevuld, en het filter Bron gewijzigd zet ze op een rij. Een bericht-id is een hash van het bericht, dus in principe levert het Engels aanpassen een nieuw id op en past de oude vertaling gewoon niet meer; in de praktijk worden ids ook met de hand meegedragen, van een alias voorzien en tussen bestanden gekopieerd, en een vertaling die geschreven is voor een zin die sindsdien veranderd is, is precies het soort verkeerde tekst dat ongemerkt meegaat.
Veelgestelde vragen
Wordt mijn bestand ergens geüpload?
Nee. Het wordt gelezen met de bestands-API van de browser zelf en geparst door de XML-parser van de browser zelf, in de pagina. Er is geen verzoek, geen account en geen opslag: het tabblad sluiten kost je je bewerkingen, en dat is de ruil voor niets dat de machine verlaat.
Waarom is elke vertaling leeg na ng extract-i18n?
Omdat extractie een bronbestand oplevert, geen vertaling. Angular schrijft de berichten die het vond en helemaal geen vertalingen; messages.xlf is het sjabloon waar elke messages.<locale>.xlf uit gemaakt wordt. Stel de doeltaal in, vertaal, en download onder de naam van de locale.
De build zegt dat er een vertaling ontbreekt. Waarom?
Met i18nMissingTranslation: "error" faalt Angular als een bericht in de bron geen eenheid heeft in het localebestand, meestal omdat het bestand geëxtraheerd is voordat het bericht bestond. Extraheer opnieuw, voeg samen met het bestand dat je al hebt, en het id staat er. Een lege <target> is een ander soort fout: die compileert, en levert een lege string.
Hoe open ik een .xlf-bestand?
Zet het op deze pagina neer, of gebruik de bestandsknop. Er valt niets te installeren en er is geen account voor nodig. Op een desktop kun je het ook in elke teksteditor openen, want XLIFF is XML, maar dan lees je markup in plaats van zinnen. Een CAT-tool zoals memoQ, Trados of Phrase opent er ook een, en dat is het juiste antwoord als je voor je brood vertaalt in plaats van één bestand na te kijken.
Is dit een viewer of een editor?
Allebei, en het verschil is of je op downloaden drukt. Een bestand openen verandert niets op schijf, dus het werkt als gewone viewer of reader om na te kijken wat een vertaler geleverd heeft, één tekst te zoeken, of te tellen wat er nog ligt. Het bestand waarmee je begon blijft hoe dan ook onaangeroerd.
Kan het .po, .resx of .json openen?
Nee. Dit leest XLIFF, het formaat dat Angular, .NET, iOS en de meeste CAT-tools uitwisselen. Andere formaten zijn een andere parser en een andere set regels over wat er verloren mag gaan.
Hoe groot mag een bestand zijn?
Tot 20 MB, en dat is ver voorbij elk echt vertaalbestand: een paar duizend eenheden blijft normaal onder een megabyte. Elke eenheid wordt in de lijst getekend, en de rijen buiten beeld kosten niets tot je ernaartoe scrolt.