Localizely logo
  • Home
  • Getting started
  • How it works
  • Pricing
  • FAQ
Sign up

I18n questions · XLIFF

What is the difference between XLIFF 1.2 and XLIFF 2.0, and how do I convert between them? 

They are two different XML vocabularies that share a name. XLIFF 1.2 became an OASIS Standard in February 2008; XLIFF 2.0 followed in August 2014 and was revised as 2.1 in February 2018. The 2.x specification states that its documents cannot be conformant to 1.2 and that 2.x applications are not required to read 1.2. Editing version="1.2" to version="2.0" therefore produces a file that is valid in neither: the namespace, the element names and the structure all differ.

The main differences:

  • Structure: 1.2 nests <xliff>, <file>, <body>, <trans-unit> with <source> and <target>; 2.x nests <xliff>, <file>, <unit>, <segment> with <source> and <target>, and a unit may be split into several segments.
  • Languages: 1.2 puts source-language and target-language on each <file>; 2.x puts srcLang and trgLang once on the root.
  • Namespace: urn:oasis:names:tc:xliff:document:1.2 versus urn:oasis:names:tc:xliff:document:2.0 (2.1 keeps the 2.0 namespace with version="2.1").
  • Inline codes: <g>, <x/>, <bpt>/<ept>, <ph> in 1.2; <pc>, <ph>, <sc>/<ec> with the original markup in <originalData> in 2.x.
  • Workflow state: 1.2 has ten state values on <target> (new, translated, signed-off, final and others) plus approved on <trans-unit>; 2.x has four on <segment>: initial, translated, reviewed, final.
  • Modules: 2.x adds optional modules for translation candidates, glossaries, metadata, format style, size restrictions and validation.
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
  <file original="app" source-language="en" target-language="de" datatype="plaintext">
    <body>
      <trans-unit id="greeting">
        <source>Hello</source>
        <target state="translated">Hallo</target>
      </trans-unit>
    </body>
  </file>
</xliff>
<xliff version="2.0" xmlns="urn:oasis:names:tc:xliff:document:2.0" srcLang="en" trgLang="de">
  <file id="f1">
    <unit id="greeting">
      <segment state="translated">
        <source>Hello</source>
        <target>Hallo</target>
      </segment>
    </unit>
  </file>
</xliff>

Which one you get is decided by the exporter. Xcode writes 1.2 (its XLIFF uses <trans-unit>), Angular's ng extract-i18n writes 1.2 by default and 2.0 with --format=xlf2, and Symfony's translation:extract defaults to xlf12 with xlf20 as the alternative. Poedit and OmegaT open both; parts of Okapi's XLIFF 2 support are still documented as experimental, so 1.2 is the safer choice when the receiving tool is unknown.

Converting an existing file: prefer re-exporting from the source tool in the version the consumer accepts, because the exporter knows the original ids and placeholders. If you only have the file, the Okapi Framework reads both versions through its XLIFF and XLIFF-2 filters and writes either: Rainbow's Translation Kit Creation step offers a Generic XLIFF (1.2) and an XLIFF 2.0 package format, and Tikal's tikal -x extracts any supported input, including an XLIFF 2 document, into a 1.2 file that tikal -m merges back after translation. Check ids, notes and inline codes afterwards; Okapi's own docs list comments and original formatting as things the XLIFF 2 round trip loses. If a tool only accepts 1.2, export 1.2 at the source and skip the conversion.

Published Oct 9, 2026 · Markdown version

Related XLIFF questions:

XLIFF file format:

Learn about the XLIFF file format
Localizely logo
About
Free tools
Boring stuff
  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • Compare
Newsletter
Copyrights 2026 © Localizely