MQXLIFF files
The bilingual export from memoQ. Like SDLXLIFF it is XLIFF 1.2 with a vendor namespace on top, but it solves the same problems in a noticeably lighter way: the confirmation level, the match rate and the change log all sit as attributes on the trans-unit itself.
The mq namespace
The first surprise is the namespace URI. It is not a URL, not a URN, just the bare
string MQXliff:
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:mq="MQXliff" version="1.2">
<file original="AdminGuide.docx" source-language="en" target-language="hu"
datatype="x-mq-doc" mq:filename="AdminGuide.docx" mq:package="AdminGuide-hu.mqout">
<header>
<phase-group>
<phase phase-name="translation" process-name="translation" tool-id="memoQ"
date="2026-05-12T09:14:22Z" contact-name="translator1"/>
</phase-group>
<tool tool-id="memoQ" tool-name="memoQ translator pro" tool-version="11.2.9"/>
</header> That is legal — a namespace name only has to be a URI reference, and a bare relative reference qualifies — but strict validators complain about it and some libraries normalize it away. It is worth knowing before you spend an afternoon deciding your file is broken.
The prefix is conventionally mq, but the prefix
is not the contract; the namespace is. xliff.ai reads the actual
xmlns: declaration off the root and follows
whatever prefix that document bound, so a re-prefixed export still round-trips.
The header carries a <phase-group> listing
the workflow steps the file has been through, each with a contact name and a date, plus
a <tool> element naming the version that
produced it. The file element adds
mq:filename and
mq:package, which is how a delivered bilingual
finds its way back into the right document in the right package.
Status is on the trans-unit
The XLIFF 1.2 state attribute on
<target> is usually absent from these
files, and it is not where the confirmation level lives.
mq:status on
<trans-unit> is.
<trans-unit id="3" mq:status="ManuallyTranslated" mq:percent="100"
mq:lastchangeduser="translator1" mq:lastchangeddate="2026-05-12T10:05:18Z"
mq:firstlastchangeduser="translator1">
<source>Export the project before you archive it.</source>
<target>Exportálja a projektet, mielőtt archiválná.</target>
</trans-unit>
<trans-unit id="6" mq:status="Reviewer1" mq:lastchangeduser="reviewer1"
mq:lastchangeddate="2026-05-18T12:03:31Z">
<source>Welcome back. You have unread notifications.</source>
<target>Üdvözöljük újra. Olvasatlan értesítése van.</target>
<mq:comment mq:author="reviewer1" mq:timestamp="2026-05-18T12:03:31Z"
mq:type="Comment" mq:deleted="false">Kept the formal register here.</mq:comment>
</trans-unit> | mq:status | What it means |
|---|---|
| NotStarted | Nobody has confirmed the row. Normally an empty target, but a pre-translated hit that was never confirmed sits here too. |
| PartiallyEdited | Someone typed in the row and moved on without confirming it. |
| ManuallyTranslated | Confirmed by the translator. The ordinary result of confirming a row. |
| Edited | A translation memory, fragment or machine hit that a human then edited and confirmed. Counted as translated. |
| Proofread | Confirmed in the proofreading step. |
| Reviewer1 | Confirmed by the first reviewer role. |
| Reviewer2 | Confirmed by the second reviewer role — the end of the default workflow. |
| Locked | Not a confirmation level. It appears alongside mq:locked="true" and means the row is read-only. |
The two reviewer levels are the part that trips people up. They are not seniority
grades; they are the two review roles in the default workflow, and a row confirmed by
the second reviewer is as finished as the format gets. xliff.ai reads
Proofread and
Reviewer1 as reviewed and
Reviewer2 as final. A status string that is not
in the list above — the vendor adds levels over time — is kept exactly as written and
the row's state is inferred from whether the target holds text.
Match rate and change log
mq:percent is the match rate the row was
populated with: 85 for a fuzzy hit, 100 for an exact one, and values above 100 for
matches whose surrounding context also matched — a 101 is a context match, not a
rounding error. A row with no percent was typed from scratch.
mq:lastchangeduser and
mq:lastchangeddate record who last touched the
row and when, in UTC.
mq:firstlastchangeduser keeps the name of the
first person who worked on it, which is what survives a row passing through translation
and then two review steps.
These are audit data, and xliff.ai does not forge them. Editing a row here changes the
target text and, if you change the status, the
mq:status attribute — nothing else. Your name
does not appear in the file, and the previous contributor's name is not overwritten with
it. If your workflow needs the change log updated, confirm the rows in the tool that
owns the workflow after you deliver.
Comments and locked rows
Comments are simpler here than in the other vendor dialect: a
<mq:comment> element sits directly inside
the trans-unit it belongs to, with
mq:author,
mq:timestamp,
mq:type and an
mq:deleted flag — deleted comments stay in the
file, marked. There is no separate definitions block and no anchor into the middle of
the target, so nothing breaks when the target text changes.
A locked row carries mq:locked="true", and
frequently mq:status="Locked" as well. Project
managers lock repeated content, product names and anything already approved. xliff.ai
shows locked rows in the grid, greyed and read-only: you can read them, search them and
copy from them, and an export leaves their bytes exactly as they arrived.
UTF-16 files
Some of these exports are UTF-16, usually little-endian with a byte-order mark, while others are UTF-8. Both are valid and both turn up in the same project. The practical symptoms of UTF-16 are familiar: the file is roughly twice the size you expected, and a text editor that assumes UTF-8 shows a null byte between every character.
xliff.ai detects the encoding from the byte-order mark, falls back to sniffing the XML declaration when there is none, and decodes strictly — a file whose bytes do not match its detected encoding fails when you open it rather than silently producing damaged output hours later. Replacement text is encoded back into the file's own encoding, and the byte-order mark stays where it was. A UTF-16 file exports as a UTF-16 file, the same length in bytes as the one you opened if you changed nothing.
Inline tags
Inline codes use ordinary XLIFF 1.2 elements —
bpt,
ept,
ph,
x — with the native markup escaped inside them,
plus occasional mq attributes such as
mq:nomap on a placeholder that has no counterpart
in the source document's tag map. The
XLIFF 1.2 inline tag reference applies without changes. Vendor attributes on those tags survive an export for the same
reason everything else does: they are never written.
What an export changes
The rule for this format is short. Never rewrite an
mq: attribute you did not change. xliff.ai keeps
the original bytes, splices the target content of the segments you edited, and edits the
mq:status attribute in place on the trans-unit
tags whose status you changed. Percent, both user attributes, the timestamp, comments,
the phase group, the tool element and every attribute nobody has documented come back
byte for byte.
Open a file, change nothing, export it, compare the bytes: identical, including the byte-order mark and the line endings. Change three rows and three target ranges differ, plus three attribute edits. That comparison is an automated test in this project, run against real exports in both encodings.
Related formats
XLIFF 1.2 describes the structure underneath. SDLXLIFF is the equivalent dialect from Trados Studio, which keeps its confirmation levels in a separate block rather than on the unit. XLIFF 2.0 is the standard both dialects would have needed less of.
Reusing a finished bilingual: convert it to TMX.