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.
Code
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()
Report a problem with this exampleOpens a pre-filled issue on GitHub.