Schedule file formats: P6 XML, MSPDI and SDEF
Four formats reach the reader: Primavera P6 XER, Primavera P6 XML, Microsoft Project MSPDI, and the USACE Standard Data Exchange Format. XER has two pages of its own — what an XER file is and decoding a P6 calendar — so this page is about the other three, and about what moves between them.
The short version is that the four formats are not four spellings of one thing. They carry different facts, and a schedule that arrives in the wrong one arrives smaller than it left.
The format is decided by the contents, not the extension
Both Primavera's XML export and a Microsoft Project MSPDI file are called
.xml, and their schemas are incompatible. Choosing by extension gets one of
them wrong roughly half the time, and the failure is not an error message — it
is a schedule. So detection reads the first few thousand characters and looks
for a positive marker:
| Format | What identifies it |
|---|---|
| P6 XER | the first record is ERMHDR, or a %T table marker survives in a damaged file |
| P6 XML | the document element is APIBusinessObjects |
| MSPDI | the Microsoft Project namespace appears in the header |
| USACE SDEF | the first non-blank record begins VOLM |
A P6 XML export renamed to .mspdi is still read correctly. A fixed-width
report that is not SDEF is refused rather than parsed into a schedule, and a
file matching none of the four is refused by name, with the four markers listed
so the sender can see which one their file was expected to carry.
Primavera P6 XML
P6 XML is the format that can carry a series. An XER is what a planner exports
for a routine transfer and it does not carry baselines; a P6 XML document
carries them as additional <Project> elements in the same file, along with the
global calendars a restricted XER omits. Baseline comparison needs two
schedules, and a windows analysis needs several, so the format that can hold
more than one project is the format a multi-update claim should arrive in.
Reading XER only means asking for eleven separate exports and hoping every data
date survived being exported by hand eleven times.
Three things about P6 XML routinely produce a plausible wrong answer rather than an error, and they are worth knowing whoever reads the file:
<Type>is overloaded. A calendar has one, an activity has one, a relationship has one, and a user-defined field has one. They are only distinguishable by their parent element, so nothing here searches forTypeacross the document.- Durations and lags are hours, not days. A planned duration of
360.0is forty-five days at eight hours a day. - Percent complete is a fraction. A finished activity carries
1.0, where MSPDI would carry100. Read a P6 file with the MSPDI convention and every completed activity becomes one percent complete — the schedule still computes, it simply reports a project that has barely started.
Exports also vary in how they declare namespaces: some put a default xmlns on
the root, some carry only a schema location and leave element names bare. Both
are in the wild, so every lookup strips the namespace instead of matching one.
Matching a fixed namespace would read one vendor's export correctly and find no
activities at all in the other's, which is an empty schedule rather than a
failure.
What P6 XML does not bring across here. This reader carries no resource and no assignment in either direction, which means no unit rate, no budgeted cost and no resource name reaches anything downstream. That is stated rather than absorbed: when a document contains resource or assignment elements, the report names them and says how many were dropped. A cost, quantity or resource-loading question wants the XER.
Microsoft Project MSPDI
MSPDI is Microsoft's documented XML interchange for MS Project: tasks, predecessor links, calendars with their exceptions, actual dates, remaining duration and the status date. Its traps are the mirror image of P6's.
- Durations are ISO-8601.
PT40H0M0Sis forty hours — five days at eight, four at ten. Reading the leading digits gives forty days. - The link type is an integer and the ordering is not alphabetical. It runs finish-to-finish, finish-to-start, start-to-finish, start-to-start. Guessing alphabetically turns every start-to-start into a finish-to-finish and back, and the result computes cleanly and is wrong.
UIDis notID.IDis the visible outline row number and is reassigned when tasks move;UIDis stable and is what links reference. Keying onIDsilently re-points relationships after any re-sort.
MS Project also has no constraint that overrides network logic, so P6's two mandatory constraint types cannot survive the trip. They are written as the closest thing the format has — a two-sided pin — and the narrowing is recorded. The same applies in the other direction to Microsoft's own two-sided constraints: reading "must start on" as a one-sided floor leaves the early dates identical, drops the late half, and silently invents float that the activity does not have.
MSPDI has no field for a planner's activity code. Its three task identifiers are two integers and a breakdown-code string, so an Oracle-style activity code has no native home in the format at all — a fact about the schema, not about any particular writer. As with P6 XML, no resource or assignment is carried.
USACE SDEF
SDEF is the odd one out: a fixed-column ASCII format, 132 characters to the record, defined in Appendix A of USACE ER 1-1-11. It matters because a federal specification points at it. UFGS 01 32 01.00 10 normatively incorporates five documents, and the note above section 1.1 says that a contractor scheduling by an in-house program "will require use of the Standard Data Exchange Format (SDEF) ... See ER 1-1-11, Appendix A".
The record types run in a fixed sequence — volume, project, calendar, holidays, activities, predecessors, units, progress, end — and each field occupies a stated span with a single blank column between neighbours. In a fixed-column format an off-by-one span is a wrong value rather than a parse error, so this reader checks the separators back: any non-blank character sitting in a column the layout calls a separator is reported with the column number and the two fields it sits between. An activity id of twelve characters in a ten-column span leaves a stray digit in the separator column and is named there.
Three properties of the format are worth knowing before you rely on it:
- The calendar code is a single character. Holidays arrive fifteen dates to a record.
- There is no start-to-finish relationship. The format defines three predecessor types, and start-to-finish is not among them.
- There is no milestone concept and no zero-duration rule. A zero duration stays a zero-day task here, because inferring a milestone from a duration is how a garbled character once turned a five-day activity into a milestone with an empty log.
The progress record carries the source tool's own early dates, late dates and total float. Those are read and shown, and they are fed to nothing: importing another tool's computed answer into our own forward and backward pass is the one mistake this project has already paid for and written up. The project end date in the header is treated the same way — carried as information, never as a deadline the backward pass must meet.
Why a binary .mpp is not read
.mpp is proprietary and undocumented. There is no published grammar to read it
against, so any reader is a reconstruction, and a reconstruction that is wrong
about one field produces a schedule rather than an error. Export from Microsoft
Project as XML instead — File → Save As → XML — and the MSPDI reader above
takes it.
What each format carries
Read as what reaches the analysis from a file of this type, not as what the format is theoretically capable of.
| Carries | XER | P6 XML | MSPDI | SDEF |
|---|---|---|---|---|
| Activities, durations, actual dates | yes | yes | yes | yes |
| Relationships and lags | yes | yes | yes | three types; no start-to-finish |
| Calendars and exception days | yes | yes, including global calendars | yes | single-character codes, 15 holidays per record |
| Resources and assignments | yes | no — reported as dropped | no — reported as dropped | no resource entity; quantities and unit cost land on the activity |
| Costs | yes | no | no | unit cost and cost to date, per activity |
| Activity codes | yes | no | no | the record's own coded fields |
| User-defined fields | yes | no | no | the unit and workers fields |
| Scheduling options (retained logic, float basis, lag calendar) | yes | yes | no | no |
| Several projects or baselines in one file | several projects | yes — projects and baselines | one | one |
What a conversion costs
Every route through a second format is lossy, and the loss is quiet. Moving an XER through P6 XML or MSPDI drops every resource, every assignment and every cost. Moving anything into MSPDI drops the activity code into a field a real Microsoft export uses for something else, and downgrades a mandatory constraint to a pin. Moving into SDEF drops any start-to-finish relationship, because the format has nowhere to put one.
None of that is an argument against the other three formats. It is an argument for sending the format the question needs: a cost or resource question wants the XER; a baseline or windows question wants the P6 XML; a USACE submission is governed by what the contract's own specification names.
This tool will not hand back a converted schedule in any case. It contains writers and no shipped command reaches one, because UFGS 01 32 17.00 20 makes third-party processing of an XER cause for rejection — what a contractor submits must come out of their own Primavera.
Read is not the same as evidenced
The four readers are not equally supported by evidence, and saying so is the point of this page.
Every file in the validation corpus is an XER. No P6 XML or MSPDI file produced by Primavera or by Microsoft Project has been read by this engine, and no real SDEF file has been read by anyone on this project — the SDEF reader was written from the published specification and is exercised against fixtures derived from that text. A fourth format is a fourth thing unproven, not a fourth thing proved.
What that means in practice: the XER route is the one with an independent check behind it, and is this real? describes what that check is and how to re-run it. Limitations states what the other three readers rest on. If you have a real P6 XML, MSPDI or SDEF export and the contractual freedom to share it, that is the single most useful thing anyone could send.
Related
- What an XER file is — the record grammar, the header, the encoding question
- Inside
clndr_data— how a P6 calendar is stored - What it does — the commands and what each one reads
- Verification — reproducing a result from the record
- Glossary
Source: web/pages/schedule-formats.md. Source commit date: 2026-09-11.