XPS File Documentation


Summary

An XML Paper Specification (XPS) file is Microsoft’s fixed-layout document format, its answer to PDF, introduced with Windows Vista in 2006. Internally it is a ZIP archive (Open Packaging Conventions) of XML page descriptions, embedded fonts and images, so it carries the MIME type application/vnd.ms-xpsdocument and the extension .xps. On Windows 10/11 open it with the optional XPS Viewer; the most common task is converting XPS to PDF.

Technical details

FeatureValue
Full nameXML Paper Specification (XPS)
File extension.xps
MIME typeapplication/vnd.ms-xpsdocument
Format typeFixed-layout document package (electronic paper)
DeveloperMicrosoft
Initial release2006 (Windows Vista / .NET Framework 3.0)
StandardMicrosoft XPS spec; successor OpenXPS standardised as ECMA-388 (2009)
Open standardPartial — original XPS is Microsoft’s; only OpenXPS (.oxps) is Ecma
Container / base formatZIP archive following Open Packaging Conventions (same as .docx)
Page markupXPS FixedPage XML (a subset of XAML)
CompressionDEFLATE (ZIP), per part
Byte orderN/A at package level; ZIP fields little-endian
Magic number50 4B 03 04 (ZIP local file header, “PK”)
Fixed layoutYes — non-reflowable, print-exact pages
EmbedsFonts (often obfuscated), raster images, print tickets, thumbnails
Digital signaturesYes — via OPC digital-signature parts
TextUnicode glyph runs (searchable / extractable)
Standardised successorOXPS (OpenXPS, ECMA-388), default on Windows 8+
Related extensions.oxps, .pdf, .zip, .dwfx
Specificationlearn.microsoft.com/windows/win32/printdocs/documents
File signature (magic bytes)
50 4B 03 04

Offset 0, 4 bytes, ASCII PK\x03\x04. This is the standard ZIP local file header, not an XPS-specific marker: an .xps is a ZIP archive built to the Open Packaging Conventions, the same container used by .oxps and .docx. You can rename the file to .zip and open it to inspect the parts. What tells an XPS apart from any other OPC package is the internal part names and namespaces — original XPS uses /FixedDocSeq.fdseq and the Microsoft XPS namespace, whereas OpenXPS uses the ECMA-388 namespace.

What is an XPS file?

XPS stands for XML Paper Specification, Microsoft’s fixed-layout “electronic paper” document format, introduced with Windows Vista and the .NET Framework 3.0 in 2006 as a competitor to Adobe’s PDF. Like PDF it stores a finished, non-reflowable page: vector graphics, embedded fonts, and text positioned exactly where it will print, so the document looks identical on any screen or printer regardless of the software that renders it. It is not meant to be edited like a word-processing document; it captures appearance, not editable structure.

Technically an .xps file is a ZIP archive that follows the Open Packaging Conventions (OPC) — the same container standard used by .docx and the rest of Office Open XML — holding XML page descriptions, fonts, images and print tickets. Because the wrapper is ordinary ZIP, you can rename the file to .zip and look inside. XPS was later standardised by Ecma International as OpenXPS (ECMA-388, 2009); that flavour uses the .oxps extension and is what Windows 8 and later produce by default, while .xps is the original Windows 7-era flavour. The rest of this article walks through the OPC package and the FixedPage markup that describe a page.

The OPC package: parts, relationships and content types

Open the archive and you find not a flat list of files but an OPC package: a set of parts (the streams inside the ZIP), tied together by relationships and catalogued by a content-type map. Three pieces make the package self-describing:

/[Content_Types].xml              content-type map for every part in the ZIP
/_rels/.rels                      package-level relationships (entry points)
/FixedDocSeq.fdseq                the fixed document sequence: lists documents
/Documents/1/FixedDoc.fdoc        one document: ordered list of its pages
/Documents/1/Pages/1.fpage        page 1 markup (FixedPage)
/Documents/1/Pages/_rels/1.fpage.rels   what page 1 references (fonts, images)
/Resources/Fonts/*.odttf          embedded, obfuscated OpenType fonts
/Resources/Images/*.png|jpg|tiff  embedded raster images
/Metadata/                        thumbnails, print tickets, core properties

[Content_Types].xml maps each part to a MIME type either by file extension (a Default element, e.g. every .fpage is XPS page markup) or by exact part name (an Override). This is how a reader knows a part is a page, a font or an image without guessing from the name. The _rels folders hold relationship files: /_rels/.rels names the package’s starting point (the fixed document sequence), and each part that references others has a matching _rels file listing those links by ID and type. That indirection is what lets a page say “draw image R1” while the actual path to the image lives in the relationships part, so resources can be shared and relocated without editing the page markup.

FixedDocSeq, FixedDocument and PageContent

The content itself is a three-level tree, mirrored by three part types. At the root, the FixedDocumentSequence (FixedDocSeq.fdseq) is the entry point and lists one or more documents in order. Each FixedDocument (FixedDoc.fdoc) lists its pages as a series of PageContent elements, each pointing to one page part. This is the same hierarchy the original document described, now made explicit:

<FixedDocumentSequence>
  <FixedDocument>
    <PageContent Source="Pages/1.fpage" />
    <PageContent Source="Pages/2.fpage" />
  </FixedDocument>
</FixedDocumentSequence>

Each PageContent references its page by a package-relative path in the Source attribute. Splitting the sequence, the document and the pages into separate parts means a reader can present page 1 while page 2 is still being loaded, and a print pipeline can spool one .fpage at a time. The order of PageContent elements is the reading and printing order; there is no separate page-index table.

Inside an .fpage: FixedPage, Glyphs and Path

Every page is a single XML part whose root is a FixedPage element declaring the page size in device-independent units of 1/96 inch. A page contains no paragraphs or flowing text: it is a flat list of absolutely positioned drawing primitives, chiefly Glyphs for text and Path for vector shapes and image fills.

<FixedPage Width="816" Height="1056" xml:lang="en-US"
           xmlns="http://schemas.microsoft.com/xps/2005/06">
  <Glyphs Fill="#ff000000"
          FontUri="/Resources/Fonts/A1B2.odttf"
          FontRenderingEmSize="16"
          OriginX="96" OriginY="120"
          UnicodeString="Invoice"
          Indices="44,81,89,82,76,70,72" />
  <Path Fill="#ffcccccc" Data="M 96,140 L 720,140 720,142 96,142 Z" />
</FixedPage>

The Glyphs element is the heart of XPS text. OriginX/OriginY fix the baseline start in 1/96-inch units, FontUri points at the embedded font part, and FontRenderingEmSize gives the point size. Crucially, Glyphs carries both a UnicodeString (the characters, which is what makes XPS text searchable and extractable) and an Indices list of glyph IDs and advance widths into that font (which is what makes rendering pixel-exact). Because both the codepoints and the exact glyph placement are stored, the page prints identically everywhere yet still yields real text when you search or copy. A Path element draws vector geometry: its Data attribute is a compact path-mini-language (moveto M, lineto L, curve, close Z) and its Fill can be a solid colour, a gradient, or an ImageBrush that references an embedded image part — which is how photos are placed on the page.

Embedded fonts and the .odttf obfuscation

To guarantee that a page looks the same on a machine that lacks its fonts, XPS embeds the fonts it uses inside the package under /Resources/Fonts/. You will notice the files carry an .odttf extension rather than .ttf or .otf. These are ordinary OpenType/TrueType fonts whose first 32 bytes have been XOR-obfuscated with a key derived from the GUID in the font part’s file name. This is not encryption or DRM — the key is sitting in the file name, and the transformation only touches the header — it is a deliberate, easily reversible scrambling so that a browser or OS font-scanner does not mistake an embedded, licence-restricted font for one it may install system-wide. A reader reverses the XOR on load and hands a normal font to its rasteriser.

How XPS files get created: the virtual printer and print tickets

Users almost never make XPS files on purpose. They appear when someone prints to the “Microsoft XPS Document Writer”, a virtual printer that, instead of sending pages to hardware, serialises the print job to an .xps file — often chosen by accident in the printer list instead of a real printer or “Microsoft Print to PDF”. This printing origin is baked into the format: XPS is also the native spool format of the Windows print pipeline since Vista, so a document is turned into XPS FixedPage markup on its way to many printers whether or not a file is ever saved. That is why the package can carry print tickets, XML parts (using the Print Schema) that describe job settings like duplexing, paper size and copies, attached at the job, document or page level.

Microsoft has since deprecated its XPS components. The XPS Viewer is no longer preinstalled — it was removed from default Windows 10 installs in version 1803 (April 2018) and is not present on Windows 11 unless you add it — which is the single biggest reason people find that double-clicking an .xps does nothing. On Windows 10/11 you add it back under Settings > Apps > Optional features > “XPS Viewer”. Cross-platform, MuPDF renders XPS natively and mutool convert -o out.pdf file.xps turns it into a PDF; on Linux, Okular opens XPS directly. Because XPS stores Unicode glyph runs, mutool convert -F text file.xps can even extract the page text.

XPS versus OXPS: same container, different namespace

XPS and OXPS are structurally near-identical — both are OPC/ZIP packages of FixedPage markup — but they are not mutually compatible, and the difference is mostly one of XML namespaces and part names. Original XPS uses the Microsoft XPS namespace (schemas.microsoft.com/xps/2005/06) and names its entry part /FixedDocSeq.fdseq. OpenXPS, standardised as ECMA-388 in 2009, uses the OpenXPS namespace and slightly different conventions, and is what Windows 8 and later write by default. The practical consequence is real: the Windows 7-era XPS Viewer cannot open an .oxps file, and Microsoft ships a free command-line XpsConverter tool (part of the Windows Driver Kit) that translates between the two flavours precisely because the wrappers are the same but the vocabularies differ. If a legacy application accepts only one flavour, that converter is the bridge.

References