docx/ole-embed

A document embedding a linked/embedded OLE object (w:object / o:OLEObject). The embed is stored as `word/embeddings/oleObject1.bin` (typically an OLE compound document wrapping, e.g., an Excel sheet) and referenced from the body via a w:object element whose child OLEObject carries an r:id pointing at the oleObject relationship.

Library verdicts: python-docx: — docxjs: —

Metadata

Feature iddocx/ole-embed
Formatdocx
Categoryimages
Spececma-376-5-part-1 § 17.3.3.19 w:object

XPath assertions

ID / partPredicateXPathpython-docxdocxjs
ole-object-binary-present
word/embeddings/oleObject1.bin
exist
The package must contain the embedded OLE binary part at `word/embeddings/oleObject1.bin`. The XPath `/` selects the document root; if the part is missing the assertion fails at the part-loading stage.
/
w-object-with-oleobject-rid-present
word/document.xml
exist
At least one <w:object> in the body must contain an <o:OLEObject> whose r:id attribute references an OLE-object relationship. (The r:id need not resolve — readers tolerate dangling OLE refs — but the attribute must be present for the OLE element to be well-formed.)
//w:object/o:OLEObject[@r:id]
ole-object-relationship-present
word/_rels/document.xml.rels
exist
The document's relationships part must carry at least one relationship of type `oleObject`, binding a w:object element to its embedded binary.
//rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject']

Render assertions

No render assertions declared.

Generator source

scripts/gen_ole_embed.py

#!/usr/bin/env python3
"""Generate ``fixtures/docx/ole-embed.docx``.

python-docx has read support for embedded OLE objects (``w:object`` /
``o:OLEObject``) but authoring a new OLE object from scratch requires
packaging a valid OLE compound document — a binary authoring surface
well outside the scope of this corpus. Instead, this generator copies
bytes from a known-working OLE-bearing fixture committed to the
python-docx repository at ``features/steps/test_files/shp-ole.docx``.

The copy is deliberately byte-for-byte — re-saving through python-docx
would defeat the purpose, potentially rewriting or dropping the
``word/embeddings/oleObject1.bin`` part and its relationship.

The source fixture contains two ``w:object`` elements: one resolved
embed (``Excel.Sheet.12`` with ``r:id="rId9"`` pointing at
``embeddings/oleObject1.bin``) and one deliberately-broken link
(``AcroExch.Document`` with a non-existent rId, exercising the
reader's tolerance for missing targets). Both are satisfied by the
assertions in ``features/docx/ole-embed.json``.
"""

from __future__ import annotations

from pathlib import Path

_REPO_ROOT = Path(__file__).resolve().parent.parent
_OUT = _REPO_ROOT / "fixtures" / "docx" / "ole-embed.docx"
_SOURCE = (
    Path.home()
    / "code"
    / "python-docx"
    / "features"
    / "steps"
    / "test_files"
    / "shp-ole.docx"
)


def main() -> int:
    if not _SOURCE.exists():
        raise SystemExit(
            f"Source OLE fixture not found at {_SOURCE}. "
            "This generator requires a checkout of loadfix/python-docx "
            "alongside this repository."
        )
    _OUT.parent.mkdir(parents=True, exist_ok=True)
    _OUT.write_bytes(_SOURCE.read_bytes())
    print(_OUT)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

Manifest (expanded)

{
  "$schema": "../manifest.schema.json",
  "id": "docx/ole-embed",
  "title": "Embedded OLE object",
  "format": "docx",
  "category": "images",
  "summary": "A document embedding a linked/embedded OLE object (w:object / o:OLEObject). The embed is stored as `word/embeddings/oleObject1.bin` (typically an OLE compound document wrapping, e.g., an Excel sheet) and referenced from the body via a w:object element whose child OLEObject carries an r:id pointing at the oleObject relationship.",
  "roles": [
    "authoring"
  ],
  "spec": {
    "source": "ecma-376-5-part-1",
    "clause": "17.3.3.19",
    "element": "w:object",
    "rnc_reference": "spec/ecma-376-5/part-1/rnc/WordprocessingML.rnc",
    "xsd_reference": "spec/ecma-376-5/part-1/xsd/wml.xsd",
    "notes": "python-docx has read-side support for embedded OLE objects but does not expose an authoring API: producing a new OLE compound document from scratch requires writing a valid OLE container binary, a task outside the scope of the library. This fixture was copied byte-for-byte from the python-docx test corpus fixture `shp-ole.docx` (source: `features/steps/test_files/`) to preserve a real OLE binary and its surrounding document markup.\n\nThe source fixture contains two w:object elements: one resolved (ProgID `Excel.Sheet.12`, r:id `rId9` pointing at the embedded oleObject1.bin) and one deliberately-broken link (ProgID `AcroExch.Document`, r:id `rIdDoesNotExist` — exercising the reader's tolerance for dangling OLE references)."
  },
  "fixtures": {
    "machine": "docx/ole-embed"
  },
  "generator": {
    "python": "scripts/gen_ole_embed.py"
  },
  "assertions": [
    {
      "id": "ole-object-binary-present",
      "part": "word/embeddings/oleObject1.bin",
      "xpath": "/",
      "must": "exist",
      "description": "The package must contain the embedded OLE binary part at `word/embeddings/oleObject1.bin`. The XPath `/` selects the document root; if the part is missing the assertion fails at the part-loading stage."
    },
    {
      "id": "w-object-with-oleobject-rid-present",
      "part": "word/document.xml",
      "namespaces": {
        "w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
        "o": "urn:schemas-microsoft-com:office:office",
        "r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
      },
      "xpath": "//w:object/o:OLEObject[@r:id]",
      "must": "exist",
      "description": "At least one <w:object> in the body must contain an <o:OLEObject> whose r:id attribute references an OLE-object relationship. (The r:id need not resolve — readers tolerate dangling OLE refs — but the attribute must be present for the OLE element to be well-formed.)"
    },
    {
      "id": "ole-object-relationship-present",
      "part": "word/_rels/document.xml.rels",
      "namespaces": {
        "rel": "http://schemas.openxmlformats.org/package/2006/relationships"
      },
      "xpath": "//rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject']",
      "must": "exist",
      "description": "The document's relationships part must carry at least one relationship of type `oleObject`, binding a w:object element to its embedded binary."
    }
  ]
}

Fixture

Download ole-embed.docx (36.0 KB)

Reference preview

No rendered reference is available for this case.

Spec notes

python-docx has read-side support for embedded OLE objects but does not expose an authoring API: producing a new OLE compound document from scratch requires writing a valid OLE container binary, a task outside the scope of the library. This fixture was copied byte-for-byte from the python-docx test corpus fixture `shp-ole.docx` (source: `features/steps/test_files/`) to preserve a real OLE binary and its surrounding document markup. The source fixture contains two w:object elements: one resolved (ProgID `Excel.Sheet.12`, r:id `rId9` pointing at the embedded oleObject1.bin) and one deliberately-broken link (ProgID `AcroExch.Document`, r:id `rIdDoesNotExist` — exercising the reader's tolerance for dangling OLE references).