“Confirmed” is not a portable concept. Every CAT tool has a status model, every model encodes a slightly different workflow, and the bilingual file is where those models have to meet. A file that leaves one tool showing 800 confirmed segments can arrive in another showing 800 drafts — nothing was corrupted, the two tools simply disagree about what a state is and where it lives.
Here is what each format actually stores.
The XLIFF 1.2 model
1.2 puts a state attribute on target, with ten defined values:
<target state="needs-review-translation">Öffnen Sie die Datei.</target>
new, needs-translation, needs-adaptation, needs-l10n,
needs-review-translation, needs-review-adaptation, needs-review-l10n,
translated, signed-off, final.
The list mixes two axes. needs-translation and needs-review-translation
describe what has to happen next; translated and signed-off describe what
already happened. The -adaptation and -l10n variants exist for workflows that
distinguish linguistic adaptation from full localization, and in practice almost
nobody writes them.
Two more attributes complicate things. state-qualifier on target records
where the translation came from — exact-match, fuzzy-match, mt-suggestion,
leveraged-tm and friends — and it is not a state, so tools reading only state
lose it. And approved="yes" on trans-unit is a separate boolean that several
tools use as their real “confirmed” flag, orthogonally to state. This editor
reads it: a segment marked translated that also carries approved="yes" is
promoted to reviewed, because that combination is what a reviewer’s sign-off
looks like in most 1.2 producers.
The XLIFF 2.0 model
2.0 cut the list to four values and moved the attribute where it belongs, onto
segment:
<segment id="s1" state="reviewed" subState="acme:proofread">
initial, translated, reviewed, final. That is the whole vocabulary. The
committee deliberately removed the “needs” family: a state should say what is
true, not what someone intends to do next.
Everything finer-grained goes into subState, which is free-form but must carry
a prefix identifying who defined it. That makes subState honest — it is
explicitly vendor-private data, and a receiving tool is not expected to
understand it. It also makes it useless for interchange, which is the trade the
committee accepted.
One thing 2.0 cannot express: the difference between a segment nobody has
touched and a segment someone started and left unfinished. Both are initial.
You tell them apart by whether target has content, which is exactly what this
editor does on read.
The SDLXLIFF model
An SDLXLIFF is XLIFF 1.2 plus an sdl namespace, and this is the trap: the
confirmation level is not in the state attribute. It lives in
sdl:seg-defs, on a sdl:seg element matched to the segment by id:
<sdl:seg-defs>
<sdl:seg id="1" conf="ApprovedTranslation" origin="tm" percent="98" locked="false"/>
</sdl:seg-defs>
Values: Draft, Translated, RejectedTranslation, ApprovedTranslation,
RejectedSignOff, ApprovedSignOff. A lock is locked="true" on the same
element.
A file exported from Trados Studio very often has no state attribute on
target at all. Feed it to a naive 1.2 reader and every segment looks
untranslated — a support ticket that gets filed against roughly every web XLIFF
tool eventually. This editor ignores the 1.2 state attribute entirely on
SDLXLIFF and treats conf as the authority.
The neighbouring attributes matter too. percent is the match rate, origin
says whether the content came from TM, MT, interactive typing or auto-propagation,
and struct-match / text-match record context-match quality. None of that is
state, none of it has an equivalent anywhere else, and all of it has to survive
a round trip untouched or the project manager’s analysis stops matching the file.
The MQXLIFF model
An MQXLIFF is XLIFF 1.2 plus an mq namespace, and it moves status somewhere
else again — onto trans-unit rather than target:
<trans-unit id="42" mq:status="Proofread" mq:percent="101" mq:locked="false">
Values: NotStarted, PartiallyEdited, ManuallyTranslated, Edited,
Proofread, Reviewer1, Reviewer2. Edited means content that arrived from a
machine or fragment source and was then touched by a human — a confirmed
translation, despite the name. Reviewer1 and Reviewer2 come from memoQ’s
two-stage review workflow, which no other tool models.
One practical detail worth knowing if you write your own parser: memoQ declares
the namespace as the bare string MQXliff, not a URI. It is legal enough for
XML but strict validators complain, and code that matches on a URI pattern will
miss it.
The mapping this editor uses
One internal state model, mapped both ways at the file boundary:
| Internal | XLIFF 1.2 state | XLIFF 2.0 state | SDLXLIFF conf | MQXLIFF mq:status |
|---|---|---|---|---|
| empty | new | initial | Draft | NotStarted |
| draft | needs-translation | initial | Draft | PartiallyEdited |
| translated | translated | translated | Translated | ManuallyTranslated |
| reviewed | needs-review-translation → translated on confirm | reviewed | ApprovedTranslation | Proofread |
| final | signed-off | final | ApprovedSignOff | Reviewer2 |
Locked is orthogonal in every model and is tracked separately, not as a state —
though memoQ does also expose a Locked status string, which this editor reads
as a lock and preserves literally.
The rule that keeps files safe is the one about unmapped values: when a file arrives with a native state the table does not cover, the original string is kept and written back unchanged unless you explicitly change that segment’s state. State derivation runs through identical code on read and on write, so a document you opened and did not edit produces zero byte changes on export. That symmetry is the whole reason a vendor file survives the trip.
What gets lost crossing tools
Some information has nowhere to go, and it is worth knowing which before you promise a client a round trip.
Rejections. RejectedTranslation and RejectedSignOff say a reviewer sent
work back. Nothing in XLIFF 1.2, XLIFF 2.0 or memoQ’s model expresses that. The
closest honest mapping degrades a rejection to “needs work”, which is why this
editor treats those as draft or reviewed by content and keeps the literal string
for the return trip.
Multi-stage review. Reviewer1 and Reviewer2 compress into one “reviewed”
notion elsewhere. Round-trip through a tool that does not model two reviewers and
the distinction is gone.
Provenance and match rates. state-qualifier, sdl:percent, mq:percent,
origin — all of it is invisible to a tool that reads only state, and all of
it is what pricing arguments are made of.
Vendor sub-states. 2.0’s subState is private by construction. Anything you
put there is a note to yourself.
Empty versus started. Lossy in 2.0 in both directions, as above.
The operational advice that follows: agree the state contract in writing before the first handoff, send a five-segment probe file through the full round trip before the real one, and never assume that “translated” means the same thing on both ends of the chain. When a status disagreement does appear, check where the status lives in the format before assuming a file is corrupt — nine times out of ten the data is still there, in an attribute the reading tool never looked at.