XLIFF 2.0 is the modern, cleaner successor to XLIFF 1.2, with a saner element hierarchy (<unit> / <segment> instead of <trans-unit>) and explicit state attributes on segments rather than on targets. Almost every modern open-source localization tool produces 2.0 by default. The catch: a depressingly large number of paid translation management systems — including some very expensive ones — still require XLIFF 1.2 on import, and silently ignore or reject 2.0 documents. The downgrade is unavoidable whenever you have to ship a translation round through a TMS that has not caught up to the 2014 spec.
i18n-convert rewrites the document tree from 2.0 into 1.2: the root <xliff> element switches to the 1.2 namespace, every <unit> becomes a <trans-unit> wrapped inside a <file><body> container, and every <segment> is collapsed into the <trans-unit> with its <source> and <target> children promoted directly underneath. Segment-level state attributes ("translated", "initial") are moved onto the <target> element using 1.2's vocabulary ("translated", "new"), so the target's translation status survives the downgrade. The srcLang and trgLang attributes on the 2.0 root are restated as source-language and target-language on <file>. The original attribute carrying the source filename is preserved.
Command
i18n-convert simple.xliff --to xliff -o output.xliff
Input
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:2.0" version="2.0" srcLang="en" trgLang="de">
<file id="f1" original="messages.json">
<unit id="greeting">
<segment state="translated">
<source>Hello</source>
<target>Hallo</target>
</segment>
</unit>
<unit id="farewell">
<segment state="translated">
<source>Goodbye</source>
<target>Auf Wiedersehen</target>
</segment>
</unit>
<unit id="untranslated">
<segment state="initial">
<source>Not yet translated</source>
</segment>
</unit>
</file>
</xliff>
Output
<?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="de" datatype="plaintext">
<body>
<trans-unit id="greeting">
<source>Hello</source>
<target state="translated">Hallo</target>
</trans-unit>
<trans-unit id="farewell">
<source>Goodbye</source>
<target state="translated">Auf Wiedersehen</target>
</trans-unit>
<trans-unit id="untranslated">
<source>Not yet translated</source>
<target state="new"></target>
</trans-unit>
</body>
</file>
</xliff>