🗂️.docx – Word als ZIP voller XML

Seit Word 2007 ist das Standardformat ein Paket nach den Open Packaging Conventions (OPC, ECMA-376 Teil 2): ein ZIP-Archiv mit XML-„Parts“, die über Relationships verknüpft sind. Der Text selbst ist WordprocessingML (ECMA-376 Teil 1). Alles unten wird live im Browser erzeugt – die fertige Datei kann man herunterladen und in Word oder LibreOffice öffnen.

🧅Drei Schichten

Wer eine .docx liest, geht von außen nach innen: erst ZIP, dann das Paket, dann das XML.

1 · ZIP-Container

Beliebiges ZIP-Programm kann die Datei öffnen. Einträge sind meist Deflate-komprimiert. Signatur 50 4B 03 04.

2 · Open Packaging Conventions

[Content_Types].xml nennt den MIME-Typ jedes Parts, .rels-Dateien verknüpfen Parts. Gleich bei .xlsx, .pptx und sogar .vsdx.

3 · WordprocessingML

Die Word-spezifische Sprache: w:document → w:body → w:p → w:r → w:t, dazu Formatvorlagen, Nummerierung, Kopfzeilen.

🤐Die ersten 64 Byte: ein ZIP-Local-File-Header

Jeder Eintrag beginnt mit einem Local File Header; am Dateiende steht das zentrale Verzeichnis, über das Programme alle Einträge finden.
0000
0010
0020
0030

Signatur: 50 4B 03 04 = „PK\x03\x04“ – Local File Header. „PK“ steht für Phil Katz, den Erfinder von ZIP.

🧪Paket-Explorer mit Absatz-Editor

Oben einen Absatz gestalten – das zugehörige w:p entsteht live, word/document.xml im Explorer ändert sich mit, und der Download ist eine echte .docx.

✏️ Absatz-Editor

r1
r2
r3
r4
r5
r6
r7
Vorschau

Dies ist fett, dies kursiv und dies blau.

🧾 Erzeugtes w:p (live)

<w:p>
  <w:r>
    <w:t xml:space="preserve">Dies ist </w:t>
  </w:r>
  <w:r>
    <w:rPr><w:b/></w:rPr>
    <w:t>fett</w:t>
  </w:r>
  <w:r>
    <w:t xml:space="preserve">, dies </w:t>
  </w:r>
  <w:r>
    <w:rPr><w:i/></w:rPr>
    <w:t>kursiv</w:t>
  </w:r>
  <w:r>
    <w:t xml:space="preserve"> und dies </w:t>
  </w:r>
  <w:r>
    <w:rPr><w:color w:val="1F4FA3"/><w:u w:val="single"/></w:rPr>
    <w:t>blau</w:t>
  </w:r>
  <w:r>
    <w:t>.</w:t>
  </w:r>
</w:p>
  • w:p = Absatz, w:pPr = Absatzeigenschaften (Formatvorlage, Abstand, Ausrichtung w:jc)
  • w:r = Lauf (run): Textstück mit einheitlicher Formatierung, w:rPr = Zeicheneigenschaften
  • w:sz zählt in Halbpunkten (11 pt → 22), w:spacing w:after in Twips (1/20 pt)
  • Leerzeichen am Rand brauchen xml:space="preserve", sonst verschluckt ein XML-Parser sie

📦 Paket-Explorer – so sieht die .docx nach dem Entpacken aus

📁 beispiel.docx
📁 _rels/
📁 docProps/
📁 word/
📁 _rels/
📁 media/
Archive:  beispiel.docx
  Length      Date    Time    Name
---------  ---------- -----   ----
     1001  01-01-1980 00:00   [Content_Types].xml
      599  01-01-1980 00:00   _rels/.rels
      654  01-01-1980 00:00   docProps/core.xml
      223  01-01-1980 00:00   docProps/app.xml
     2441  01-01-1980 00:00   word/document.xml
     1772  01-01-1980 00:00   word/styles.xml
      324  01-01-1980 00:00   word/settings.xml
      721  01-01-1980 00:00   word/_rels/document.xml.rels
      852  01-01-1980 00:00   word/media/image1.png
---------                     -------
     8587                     9 files
/word/document.xml2441 Byte
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml

Der eigentliche Text: w:body → Absätze w:p → Läufe w:r → Text w:t. Am Ende w:sectPr mit Seitengröße (A4 = 11906 × 16838 Twips) und Rändern.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing">
  <w:body>
    <w:p>
      <w:pPr><w:pStyle w:val="Heading1"/></w:pPr>
      <w:r>
        <w:t>Grüße aus VisualWord</w:t>
      </w:r>
    </w:p>
    <w:p>
      <w:r>
        <w:t xml:space="preserve">Dies ist </w:t>
      </w:r>
      <w:r>
        <w:rPr><w:b/></w:rPr>
        <w:t>fett</w:t>
      </w:r>
      <w:r>
        <w:t xml:space="preserve">, dies </w:t>
      </w:r>
      <w:r>
        <w:rPr><w:i/></w:rPr>
        <w:t>kursiv</w:t>
      </w:r>
      <w:r>
        <w:t xml:space="preserve"> und dies </w:t>
      </w:r>
      <w:r>
        <w:rPr><w:color w:val="1F4FA3"/><w:u w:val="single"/></w:rPr>
        <w:t>blau</w:t>
      </w:r>
      <w:r>
        <w:t>.</w:t>
      </w:r>
    </w:p>
    <w:p>
      <w:r><w:t xml:space="preserve">Mehr unter </w:t></w:r>
      <w:hyperlink r:id="rId4">
        <w:r><w:rPr><w:rStyle w:val="Hyperlink"/></w:rPr><w:t>example.org</w:t></w:r>
      </w:hyperlink>
    </w:p>
    <w:p>
      <w:r>
        <w:drawing>
          <wp:inline distT="0" distB="0" distL="0" distR="0">
            <wp:extent cx="952500" cy="952500"/>
            <wp:docPr id="1" name="Bild 1"/>
            <a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
              <a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
                <pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
                  <pic:nvPicPr><pic:cNvPr id="0" name="image1.png"/><pic:cNvPicPr/></pic:nvPicPr>
                  <pic:blipFill><a:blip r:embed="rId3"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>
                  <pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="952500" cy="952500"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr>
                </pic:pic>
              </a:graphicData>
            </a:graphic>
          </wp:inline>
        </w:drawing>
      </w:r>
    </w:p>
    <w:sectPr>
      <w:pgSz w:w="11906" w:h="16838"/>
      <w:pgMar w:top="1417" w:right="1417" w:bottom="1134" w:left="1417" w:header="708" w:footer="708" w:gutter="0"/>
    </w:sectPr>
  </w:body>
</w:document>

🔗Relationships: wie die Parts zusammenhängen

Kein Part verweist direkt per Dateiname auf einen anderen. Stattdessen gibt es zu jedem Part eine .rels-Datei; im XML steht nur die ID (r:id, r:embed).
_rels/.rels  (Beziehungen des Pakets)
 ├─ rId1 officeDocument ──► word/document.xml
 ├─ rId2 core-properties ─► docProps/core.xml
 └─ rId3 extended-props ──► docProps/app.xml

word/_rels/document.xml.rels
 ├─ rId1 styles ──────────► word/styles.xml
 ├─ rId2 settings ────────► word/settings.xml
 ├─ rId3 image ───────────► word/media/image1.png
 └─ rId4 hyperlink ───────► https://example.org/
                            (TargetMode="External")

word/document.xml
   <a:blip r:embed="rId3"/>        → Bild
   <w:hyperlink r:id="rId4"> …     → Link

Einstieg: Ein Programm liest zuerst _rels/.rels und sucht die Beziehung vom Typ …/officeDocument. Dass das Hauptdokument word/document.xml heißt, ist nur Konvention – ein anderer Name wäre gültig.

Ziele sind relativ zum Ordner des Quell-Parts: media/image1.png aus word/document.xml ergibt /word/media/image1.png. Die .rels-Datei zu /word/document.xml liegt in /word/_rels/document.xml.rels.

Content Types: Für jeden Part gilt zuerst ein Override mit genau seinem Namen, sonst ein Default nach Dateiendung. Groß-/Kleinschreibung spielt dabei keine Rolle.

⚠️ Externe Ziele
TargetMode="External" erlaubt Verweise ins Netz. Harmlos bei Links – aber auch Vorlagen (attachedTemplate) oder OLE-Objekte können extern sein. Genau das nutzen Angriffe wie „Remote Template Injection“.

🌳WordprocessingML: vom Dokument zum Zeichen

w:document
└─ w:body
   ├─ w:p                   Absatz
   │  ├─ w:pPr              Absatzeigenschaften
   │  │  ├─ w:pStyle        Formatvorlage (ID)
   │  │  ├─ w:spacing       Abstände (Twips)
   │  │  └─ w:jc            Ausrichtung
   │  ├─ w:r                Lauf (run)
   │  │  ├─ w:rPr           Zeicheneigenschaften
   │  │  │  └─ w:b, w:i, w:color, w:sz, w:u
   │  │  └─ w:t             Text
   │  └─ w:hyperlink r:id   Link (enthält w:r)
   ├─ w:tbl                 Tabelle → w:tr → w:tc → w:p
   └─ w:sectPr              Seite: w:pgSz, w:pgMar

Ein Lauf (w:r) ist die kleinste Einheit mit einheitlicher Formatierung. Wird mitten in einem Wort ein Buchstabe fett, entstehen drei Läufe. Word teilt Läufe außerdem oft wegen Rechtschreibprüfung oder Änderungsverfolgung (w:rsidR).

Formatierung wird vererbt: docDefaults → Absatzformatvorlage → Zeichenformatvorlage → direkte Formatierung im w:rPr. Die Überschrift im Beispiel ist nur deshalb blau und fett, weil styles.xml es für Heading1 festlegt.

Tabellen liegen neben Absätzen direkt in w:body; jede Zelle muss mindestens einen w:p enthalten. Das letzte Element von w:body ist w:sectPr mit Seitenformat und Rändern.

📏Maßeinheiten in Office Open XML

Eine häufige Stolperfalle: Jedes Teilformat zählt in einer anderen Einheit.
EinheitGrößeVerwendet fürBeispiel
Twips (Twentieth of a Point)1/20 pt = 1/1440 ZollSeitengröße, Ränder, Einzüge, AbständeA4-Breite: 11906
Halbpunkte1/2 ptSchriftgröße w:sz11 pt → 22
Achtelpunkte1/8 ptRahmenstärke w:sz in w:pBdr/w:tcBorders4 = ½ pt
EMU (English Metric Unit)1/914400 Zoll = 1/360000 cmBilder und Formen (DrawingML)1 px bei 96 dpi = 9525
Fünfzigstel Prozent1/50 %Tabellenbreite w:type="pct"5000 = 100 %