xlsx/preserve-empty-core-property-elements

python-xlsx strips empty elements from docProps/core.xml on save: <dc:creator></dc:creator> and similar are dropped when their text content is empty, even though the source fixture shipped them. That flips ~22 corpus fixtures (every xlsx/core-properties-full--*, custom-properties-types--*, extended-properties-basic--*) into tier-3 round-trip drift because each has one or more empty core-property children in its committed XML. The child-count drop of 3→2 or 4→3 in the round-trip audit traces to exactly this bug.

Library verdicts: python-xlsx: — xlsxjs: —

Metadata

Feature idxlsx/preserve-empty-core-property-elements
Formatxlsx
Categoryround-trip
Spececma-376-5-part-2 § 11.1 coreProperties

XPath assertions

ID / partPredicateXPathpython-xlsxxlsxjs
empty-creator-preserved
docProps/core.xml
exist
The source fixture ships an empty <dc:creator></dc:creator>. It must survive the round-trip. Currently FAILS — python-xlsx drops empty core-property elements on save.
//dc:creator

Render assertions

No render assertions declared.

Manifest (expanded)

{
  "$schema": "../manifest.schema.json",
  "id": "xlsx/preserve-empty-core-property-elements",
  "title": "Preserve empty core-property elements across round-trip (KNOWN FAILING — python-xlsx bug)",
  "format": "xlsx",
  "category": "round-trip",
  "summary": "python-xlsx strips empty elements from docProps/core.xml on save: <dc:creator></dc:creator> and similar are dropped when their text content is empty, even though the source fixture shipped them. That flips ~22 corpus fixtures (every xlsx/core-properties-full--*, custom-properties-types--*, extended-properties-basic--*) into tier-3 round-trip drift because each has one or more empty core-property children in its committed XML. The child-count drop of 3→2 or 4→3 in the round-trip audit traces to exactly this bug.",
  "roles": [
    "authoring"
  ],
  "spec": {
    "source": "ecma-376-5-part-2",
    "clause": "11.1",
    "element": "coreProperties",
    "notes": "OPC clause 11.1 defines the core-properties part. Elements with empty content are schema-valid — <dc:creator></dc:creator> is a deliberate authoring choice (property present, value blank), distinct from the property being absent. python-xlsx's WorkbookPackageProperties writer drops an element whenever its backing CT_* attribute is None or falsy; the round-trip load reads the empty element but can't distinguish it from missing, so the save path emits nothing. The fix is to preserve empty-but-present elements verbatim when they shipped in the source package."
  },
  "fixtures": {
    "machine": "xlsx/preserve-empty-core-property-elements"
  },
  "round_trip": {
    "library": "python-xlsx",
    "source_fixture": "xlsx/core-properties-full--modified"
  },
  "assertions": [
    {
      "id": "empty-creator-preserved",
      "part": "docProps/core.xml",
      "namespaces": {
        "cp": "http://schemas.openxmlformats.org/package/2006/metadata/core-properties",
        "dc": "http://purl.org/dc/elements/1.1/",
        "dcterms": "http://purl.org/dc/terms/"
      },
      "xpath": "//dc:creator",
      "must": "exist",
      "description": "The source fixture ships an empty <dc:creator></dc:creator>. It must survive the round-trip. Currently FAILS — python-xlsx drops empty core-property elements on save."
    }
  ]
}

Fixture

Fixture file not found on disk.

Reference preview

No rendered reference is available for this case.

Spec notes

OPC clause 11.1 defines the core-properties part. Elements with empty content are schema-valid — <dc:creator></dc:creator> is a deliberate authoring choice (property present, value blank), distinct from the property being absent. python-xlsx's WorkbookPackageProperties writer drops an element whenever its backing CT_* attribute is None or falsy; the round-trip load reads the empty element but can't distinguish it from missing, so the save path emits nothing. The fix is to preserve empty-but-present elements verbatim when they shipped in the source package.