XLIFF
XLIFF, the translation interchange format
XLIFF is how the translation industry passes work around: an OASIS standard since 2002, spoken by every serious CAT tool, emitted by Angular and exported by Xcode. Each translation unit pairs the source text with its target and a note, and that pairing is what makes agency round trips work.
This page covers the 1.2 and 2.0 anatomies, inline markup, how plurals are represented in a format that predates plural support, and where each toolchain puts the files.
<?xml version="1.0" encoding="UTF-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" target-language="fr" datatype="plaintext" original="messages">
<body>
<trans-unit id="checkout.title">
<source>Order summary</source>
<target>Récapitulatif de commande</target>
<note>Title of the checkout screen</note>
</trans-unit>
</body>
</file>
</xliff> Cheatsheet
XLIFF anatomy in five rows
<trans-unit id="…"> One translatable unit in 1.2, at any nesting depth. The id becomes the key. <unit> with <segment> The 2.0 spelling of the same thing, wrapped in a mandatory segment element. <source>, <target>, <note> Original, translation and context, imported together. An empty target is respected as deliberately empty, not skipped. <x/>, <ph>, <g> Inline placeholder markup contributes its text in place, so a unit containing tags still imports as a complete string. <group restype="x-gettext-plurals"> The OASIS convention for plurals in 1.2: one unit per CLDR form, grouped so they stay one plural. Untranslated keys, three spellings
An empty target is an explicit request to translate; an omitted unit hides the work; a source copy pre-fills it.
<trans-unit id="checkout.confirm">
<source>Confirm purchase</source>
<target></target>
</trans-unit> <!-- unit not exported --> <trans-unit id="checkout.confirm">
<source>Confirm purchase</source>
<target>Confirm purchase</target>
</trans-unit> Conventions
Where XLIFF shows up
ng extract-i18n emits messages.xlf; translations live in messages.fr.xlf .xcloc bundles carrying XLIFF translations/messages.fr.xlf .xlf exchanges cleanly; vendor dialects like SDLXLIFF are their own formats Typical flow: export XLIFF from locamorph for an agency, let them work in their CAT tool of choice, and import the handback; source, target and notes line up automatically.
The same unit in 1.2 and 2.0
Version 1.2 has the widest tool support; 2.0 wraps content in segments.
<trans-unit id="checkout.title">
<source>Order summary</source>
<target>Récapitulatif de commande</target>
<note>Title of the checkout screen</note>
</trans-unit> <unit id="checkout.title">
<segment>
<source>Order summary</source>
<target>Récapitulatif de commande</target>
</segment>
</unit> The 1.2 spec also defines target states such as new, needs-translation, translated, signed-off and final, which agencies use to track progress through a handback.
Plurals
Plurals in XLIFF
XLIFF 1.2 has no plural element, so the OASIS representation guide’s convention applies: a group holding one unit per form, suffixed with the CLDR category so partial translations keep their identity.
<group restype="x-gettext-plurals" resname="cart.items">
<trans-unit id="cart.items[one]" resname="cart.items">
<source>%d item</source>
<target state="translated">%d article</target>
</trans-unit>
<trans-unit id="cart.items[other]" resname="cart.items">
<source>%d items</source>
<target state="translated">%d articles</target>
</trans-unit>
</group> <group restype="x-gettext-plurals" resname="cart.items">
<trans-unit id="cart.items[one]">
<source>%d item</source>
<target>%d article</target>
</trans-unit>
<trans-unit id="cart.items[other]">
<source>%d items</source>
<target>%d articles</target>
</trans-unit>
</group> <group restype="x-gettext-plurals" resname="cart.items">
<trans-unit id="cart.items[one]">…</trans-unit>
<trans-unit id="cart.items[few]">…</trans-unit>
<trans-unit id="cart.items[many]">…</trans-unit>
<trans-unit id="cart.items[other]">…</trans-unit>
</group> One trans-unit per CLDR category, bracketed so partial translations keep their identity. Polish grows to four units, Arabic to six.
See the same plural in every format locamorph exports.
In locamorph
How locamorph handles XLIFF
1.2 and 2.0 in, 1.2 out
trans-unit files at any nesting depth and 2.0
unit/segment files both import. Exports use 1.2, the
dialect with the widest tool support.
Text is never guessed at
A target of 2024 stays the string it was, and notes stay attached
to their unit through import, edit and export.
Locales from the file
source-language and target-language attributes
identify the languages, so an agency handback lands in the right locale on its
own.
Convert
Convert XLIFF to and from other formats
XLIFF is the bridge format, so most conversions start or end here.
XLIFF to JSON
The agency handback into a web app.
- Import the
.xlf; languages come from its attributes. - Source, target and notes land on the right keys.
- Export as JSON for your framework.
Anything to XLIFF
Preparing an agency handoff from whatever you have.
- Import JSON, YAML, strings.xml, ARB or .properties.
- Notes become
<note>elements translators see. - Export XLIFF 1.2 per target language.
XLIFF to strings.xml
Translated units delivered straight into the Android build.
- Import the handback.
- Plural groups become CLDR forms.
- Export strings.xml per locale with escaping applied.
Related
Keep going
JSON
Agency handback in, framework ready JSON out. The classic bridge.
iOS Strings
Import Apple’s native files and hand back through XLIFF.
Amazon S3
Automate agency exchanges through a bucket both sides can reach.
Further reading
- XLIFF 1.2 specification, the dialect locamorph writes
- XLIFF 2.0 specification, also read on import
- Angular internationalization, the biggest developer side producer
Bring the agency file
Import an XLIFF handback on the free plan and watch source, target and notes land on the right keys in the right language.