Home · Free tools · XML compare

Compare two XML files

Paste or drop two XML documents. Both are parsed, then walked in parallel: you get every element and attribute that differs, each with the path it lives at — order/item[1]/@sku — rather than a wall of red lines. Indentation and self-closing tags produce no differences, because they are syntax. Neither document is uploaded.

First document paste, or drop a .xml file

Second document the version you want to check

Nothing is uploaded. The file is read by JavaScript in this tab and never leaves your computer — no server sees it, and closing the tab throws it away.

How to compare two XML files

  1. Load both documents. Paste them, or drop a .xml file onto either box. Both are parsed by the browser in this tab, with no upload.
  2. Read the differences by path. Elements and attributes are listed together, each with the path it lives at and the value on both sides.
  3. Ignore the formatting. Indentation, line breaks between tags and self-closing form produce no rows — only real differences are listed.
  4. Export the list. Download the differences as CSV, or copy them, to attach to a ticket or a change request.

Half the XML "diff" tools are text diffs wearing a label

Comparing XML as text has two failure modes that show up on the first real file. Re-indent one side, or let a serializer write <br/> where the other wrote <br></br>, and the whole document is marked as changed. Insert one element near the top and every line after it shifts, so a one-element change arrives as hundreds.

This page parses both documents first — with the browser's own XML parser, so namespaces, entities and encoding declarations behave the way they do everywhere else — and compares the trees. Formatting differences produce nothing. An inserted element produces one row.

Attributes are part of the tree

An attribute is where XML keeps most of its identifiers, and a diff that treats the start tag as a single string can only tell you the tag changed. Here each attribute is its own entry, written with an @ so it reads as what it is:

  • order/@id — the order number changed.
  • order/item[1]/@sku — the second line item points at a different product.
  • order/note — an element that exists on one side only.

Attribute order inside a tag is not meaningful in XML and is not reported. Element order is, for repeated elements, and is.

Repeated elements line up as a list

Several <item> children under one parent are treated as a sequence and compared position by position, which is what makes an inserted or removed row readable: one addition at item[3] rather than every following item marked as changed. Children with distinct names are compared by name, so their order in the file does not matter.

Text content, and the whitespace around it

Whitespace between elements is layout and is dropped: <a> <b/> </a> has no text of its own. Whitespace inside a text node is content, with runs collapsed to single spaces — so a document re-wrapped at a different line width compares as unchanged, while an actually edited sentence does not.

What it will not do

  • Validate against a schema. This compares two documents to each other, not a document to an XSD or a DTD.
  • Merge, or produce a patch. It reports the differences; it does not write a third file.
  • Repair broken XML. A document that is not well-formed is reported as such, with what the parser objected to, rather than being guessed at.

Nothing leaves this tab

XML that people need to diff is usually an invoice exchange, a configuration, a feed or a financial filing. Both documents are parsed and compared by JavaScript running on your machine. There is no request to send, so nothing to intercept, log or retain.

Questions people ask

Does it detect a changed attribute?

Yes — attributes are compared individually and reported with a path such as order/item[1]/@sku. That is the main thing a text-based XML diff cannot tell you, because it only sees that the start tag differs.

Will re-indented XML show as different?

No. Indentation, line breaks between tags and self-closing versus paired empty tags are all syntax, and produce no rows. Only the tree is compared.

Does it handle namespaces?

Yes. Parsing is done by the browser's own XML parser, so prefixed names are read the way they are everywhere else. Elements are compared by the name as written, so changing a prefix is reported as a difference — which it is, to anything reading the document by prefix.

Can I compare an SVG, an RSS feed or an XSD?

Yes — they are all XML. Drop either file in. For very large documents the preview lists the first 300 differences and the download has all of them.

Are my files uploaded anywhere?

No. The file is read by JavaScript running in this tab, using the browser's own DecompressionStream to unzip .xlsx and a parser that runs on your machine. There is no server call in the page — you can watch the network tab while you use it. Close the tab and the data is gone.

Do this on your own machine instead

TableDI is a desktop spreadsheet workspace that runs entirely on your machine. Import the file, fix it, chart it — nothing is uploaded, and there is no account to create.

Free forever, not a trial — no account, no card. macOS today; a Windows build is in progress. What the paid tier adds.

Last reviewed 2026-09-01 by the TableDI team. Something wrong on this page? Tell us — it is one inbox, read by the people who build TableDI.