Watch at EaseStories. Answers. Perspective.

Technology · PRACTICAL GUIDE

minidom adds blank lines? Verify text preservation before deleting whitespace

A cleaner XML file can contain different text. Reproduce the save cycle, check the installed Python version and compare semantic content before replacing the original.

Original diagram comparing growing blank lines, changed mixed text and a bounded toxml fallback in CPython3.12.14 fixtures.
Original technical illustration: successful XML parsing can hide added whitespace and deleted intentional blank lines. Watch at Ease

Do not remove every blank line to fix a growing XML file. First prove which whitespace is disposable and whether the installed serializer changes text; a document that still parses can already have lost meaning.

1. Freeze the save cycle and the runtime

Keep the original file and a disposable copy. Record sys.version, the parser, serialization call, indent/newl arguments and whether the input was already indented. Repeat the exact parse–edit–serialize cycle without making an edit; growing output then implicates formatting rather than your new element.

In our CPython 3.12.14 fixture, an already indented root with one item produced four blank lines after the first toprettyxml(indent=' ') call and eight after reparsing and printing again. Those counts belong to this small fixture, not every XML file.

2. Treat whitespace as possible content

Our mixed-content fixture <p>Hello <b>world</b>!</p> changed its descendant text from Hello world! to text containing added newlines and indentation. A separate <p><b>A</b> <b>B</b></p> fixture also changed the one-space separator. Counting tags or successfully parsing the result would miss both changes.

An xml:space='preserve' fixture containing an intentional blank line was still reformatted on 3.12.14; filtering the pretty output with if line.strip() removed that blank line. W3C defines preserve as an intent inherited by descendants unless overridden. It is not evidence that every installed pretty printer implements that intent.

3. Choose a bounded repair instead of a global filter

When whitespace meaning is unknown on the tested runtime, serialize the edited DOM with toxml(encoding='utf-8') and write those bytes to a new file. This avoids adding pretty-print indentation; it does not remove whitespace already present or restore content changed by an earlier save. In all four fixtures, toxml preserved parsed descendant text and a second parse–toxml cycle produced the same serialization.

Keep a formatted viewing copy separate from the stored document. Remove layout nodes only where the document's content model or application contract establishes that they are ignorable. The lxml FAQ explicitly warns that remove_blank_text uses a heuristic without definite knowledge; switching libraries is not a universal preservation proof.

4. Accept the result by meaning, not appearance

Python's3.16 development documentation records changed handling for mixed content and xml:space='preserve'. Do not assume that wording describes 3.12 or that an upgrade fixes previously altered text. We executed 3.12.14 only; rerun representative cases on the exact proposed replacement runtime.

Before replacing the original, reparse the candidate and compare ordered elements, attributes and every text run—including whitespace-only runs in protected or mixed content—using only explicitly approved layout exceptions. Test a second save and the consuming application. Keep the backup: toxml is not byte-for-byte preservation, canonicalization or a guarantee for signatures, entity spelling or every document feature. These trusted synthetic examples are not an untrusted-XML security recipe.

Original diagram showing original-file preservation, exact runtime and all text-run checks before two-save acceptance.
Original technical illustration: compare semantic text and the second save before replacing the stored XML. Watch at Ease