xmltoolskit.org
XML utilities, in the browser
Say hi →

XML Diff

updated 30 August 2026

compare two xmls
Left (old) XML
Drop left file, or
Right (new) XML
Drop right file, or
ready

XML Diff

Plain diff hates XML: reformat a file and every line is red, insert one element and everything after it shifts. This compares the two documents as trees and tells you what actually changed — this attribute, on this path, from this value to that one. The old line diff is still here as a second mode.

The two modes

Structural walks both trees together and reports each difference where it happens. Every line of the report is one change, prefixed +, - or ~, followed by the path it applies to:

~ /catalog/book[2]/@price   "19.95" → "21.50"
+ /catalog/book[3]          <book> 2 child element(s)
- /catalog/book[4]/isbn     "0-13-110362-8"
~ /catalog/book[1]/title/text()   "Old title" → "New title"

Paths are the ordinary XPath shape, numbered over the two documents read side by side, so you can paste one straight into the XPath tester to see the element in context.

Text is the previous behaviour: both documents are re-serialised with a normalised attribute order and compared line by line as a unified diff. It is the right mode when you want a patch-shaped artefact, or when the change is inside a big block of text content. It builds a table of every line pair, so it refuses documents where that would be tens of millions of cells — the structural mode has no such limit.

How children are matched

The naive comparison — first child against first child — reports an inserted element as "everything after position 3 changed". Instead, each element's children are matched with a longest-common- subsequence pass over their signatures: the element name plus its identifying attribute (id, name, key or code, whichever it has first).

So a <book id="b7"> that moved from third to first place is matched with itself and reported only for what really differs inside it, while a genuinely new record is reported as one addition rather than a cascade. It also means the report is only as good as your identifiers: a list of identical-looking elements with no distinguishing attribute is matched by position, because nothing else is available.

Options

Ignore whitespace collapses runs of whitespace inside text before comparing, so indentation changes and a reflowed line are not differences. Ignore namespace declarations hides xmlns attributes, which is what you want when one file declares prefixes on the root and the other declares them per element — the meaning is the same and the noise is considerable. In text mode the same box also sorts attributes before serialising. Ignore comments drops them from the comparison entirely.

If two files should be byte-identical after normalisation rather than merely equivalent, the canonicalizer is the stricter test: run both through it and compare the SHA-256 digests.

Privacy

100% client-side. No upload. See the privacy policy.