XML Diff

Compare two XML documents by structure, not by text lines. Attribute order and indentation are ignored, and every difference is reported with its element path — added, removed or changed. Runs in your browser; nothing is uploaded.

Try:
Diff report

About this tool

XML Diff compares two XML documents by structure, not by text lines. A line-based diff flags every re-indentation and every reordered attribute; this one parses both documents into element trees and reports only the differences that actually change the data.

Paste your first (left / old) document and your second (right / new) document. The tool walks both trees in parallel:

Worked example

Comparing

<catalog><book id="1"><title>Rust</title></book></catalog>

with

<catalog><book id="2"><title>Rust 2</title></book></catalog>

gives this report (JSON format, indent 2):

{
  "equal": false,
  "added": 0,
  "removed": 0,
  "changed": 2,
  "changes": [
    { "path": "/catalog/book/@id", "kind": "changed", "old": "1", "new": "2" },
    { "path": "/catalog/book/title/text()", "kind": "changed", "old": "Rust", "new": "Rust 2" }
  ]
}

The same comparison with Report format = text gives:

2 differences: 0 added, 0 removed, 2 changed
~ /catalog/book/@id  1 -> 2
~ /catalog/book/title/text()  Rust -> Rust 2

Options

Everything runs locally in your browser via WebAssembly — your documents are never uploaded.

Limits and edge cases

Handy for

FAQ

Does attribute order or indentation matter?

No. Attributes are compared as a sorted map, so <a x="1" y="2"/> and <a y="2" x="1"/> are equal. Indentation and line breaks are ignored too, as long as Ignore insignificant whitespace is on (it is by default) — turn it off if you need a byte-faithful text comparison.

How is a reordered document handled?

By default (Smart alignment) sibling order is significant, so swapping two children is reported as differences. Pick Ignore order — treat siblings as a set when the order carries no meaning: identical subtrees pair up in any order, then the leftovers pair up by element name.

What happens when an element is inserted in the middle of a list?

With Smart alignment the untouched siblings on both sides of the insertion are matched as anchors, so you get exactly one added entry. With By position the same edit shifts every later sibling, so you get a string of changed entries plus one added at the end — useful when position itself is what you're checking.

Are namespaces compared?

Yes, by default: ns:book and p:book are different element names even when both prefixes are bound to the same URI, and xmlns declarations are ordinary attributes. Switch on Ignore namespace prefixes to compare local names only and skip xmlns declarations entirely.

Why do I get "the first (left) XML is not well-formed"?

Both inputs must be well-formed XML, and the error names the side that failed plus the byte position. Common causes: an unclosed tag, a stray & that isn't an entity, or mismatched start/end tag names. The tool never repairs input — it only reports.

Is this the same as a text diff of the two files?

No. A text diff works line by line, so reformatting a document produces a huge diff even when nothing changed. This tool compares the parsed trees, so it reports only real structural and value differences — and it locates each one by element path rather than by line number.

Developer & Automation Access

Run it from the terminal

Same engine as this page, headless — via the gizza CLI:

gizza tool xml-diff '<catalog><book id="1"><title>Rust</title></book></catalog>' 'right=<catalog><book id="2"><title>Rust 2</title></book></catalog>'

New to the CLI? Get gizza →

Open it by URL

Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:

https://gizza.ai/tools/xml-diff/?left=%3Ccatalog%3E%3Cbook%20id%3D%221%22%3E%3Ctitle%3ERust%3C%2Ftitle%3E%3C%2Fbook%3E%3C%2Fcatalog%3E&right=%3Ccatalog%3E%3Cbook%20id%3D%222%22%3E%3Ctitle%3ERust%202%3C%2Ftitle%3E%3C%2Fbook%3E%3C%2Fcatalog%3E&strategy=lcs&ignore_whitespace=true&ignore_comments=true&ignore_namespaces=true&numeric_text=true&format=json&indent=2

Machine-readable descriptor: tool.json — title + parameters JSON Schema for agents.