Parse Large XML Incrementally with iterparse

Read a large XML document without loading it whole, yield one record at a time, and clear processed elements to free memory.

PythonData Integrity

Code

snippet
import xml.etree.ElementTree as ET
from collections.abc import Iterator
from pathlib import Path


def iter_records(path: Path, tag: str = "record") -> Iterator[dict[str, str]]:
    context = ET.iterparse(path, events=("end",))
    for _, element in context:
        if element.tag != tag:
            continue
        record = {
            child.tag: (child.text or "").strip() for child in element
        }
        yield record
        element.clear()


def write_fixture(path: Path) -> None:
    path.write_text(
        "<catalog>"
        "<record><id>1</id><name>Ada</name></record>"
        "<record><id>2</id><name>Grace</name></record>"
        "</catalog>",
        encoding="utf-8",
    )


if __name__ == "__main__":
    fixture = Path("catalog.xml")
    write_fixture(fixture)
    try:
        print(list(iter_records(fixture)))
    finally:
        fixture.unlink()