Skip to content

xmldiffreport

PyPI version Python versions License: MIT

N-way structural & semantic XML diff that produces human-readable Markdown reports — driven by per-dialect recipes.

xmldiffreport compares two or more XML files at once — BMC Control-M exports, Maven POMs, JUnit/xUnit reports, sitemaps, or any dialect you teach it with a small recipe — and tells you what actually changed, element by element and attribute by attribute, instead of a noisy line-by-line text diff. It aligns elements by a natural key (not by position), ignores volatile attributes, and writes a clean Markdown report.

It started as a way to spot differences between BMC Control-M job patches flowing through test → uat → bench → prod, and generalized into a recipe-driven engine that works on any XML dialect (Control-M exports, Maven POMs, JUnit reports, sitemaps, …).

Quickstart

pip install xmldiffreport
# Compare two (or more) XML files — uses the generic recipe by default
xmldiffreport old.xml new.xml -o report.md

Working with a known dialect (Control-M, sitemaps, …)? Add --recipe. Pass directories to compare every *.xml inside them. See Getting Started and Inputs & file layout.

from xmldiffreport import diff

result = diff(["old.xml", "new.xml"], recipe="sitemap")   # a file, files, or dir(s)
print(result.render())                                    # Markdown — or .render("html")

Why not a plain diff?

A text diff on XML lies — volatile attributes (VERSION, CREATION_TIME, JOBISN), reordered children, and attribute order all create false changes. xmldiffreport is structural, N-way (3+ files at once), and emits a review-ready report.

xmldiffreport xmldiff DiffDog / Oxygen DeltaXML
Match by declared natural key ⚠️ limited
N-way (3+ files)
Markdown report out of the box ⚠️ GUI
Open source

Next steps