Skip to content

XML Compare

Paste two XML documents to compare them by structure rather than by text. Reordered attributes, indentation and <a/> versus <a></a> are not differences — a plain text diff reports all three, and that is why it gives you the wrong answer on XML.

Runs in your browser. Nothing uploaded.

How to use it

  1. Paste both documents. Original on the left, changed on the right.
  2. Press Compare. Every difference appears with a path telling you exactly where it is.
  3. Adjust the options if your files have a convention this tool should respect.

Press “Load an example” to see the point in one click: two documents a text diff calls five differences, and this calls one.

Why a text diff gives the wrong answer on XML

Most free “XML compare” tools are text diffs with syntax colouring. They compare characters. XML is not characters — it is a tree, and the specification is explicit about which parts of the text carry meaning and which do not.

Every pair below is the same document. A text diff flags all of them.

Document A Document B Why they are identical
<a x="1" y="2"/> <a y="2" x="1"/> Attribute order is not significant in XML
<a/> <a></a> Two spellings of the same empty element
<r><a/></r> <r>⏎  <a/>⏎</r> Whitespace between elements is indentation
<a x="1"></a> <a x='1'></a> Quote style is a lexical detail
<a>&amp;</a> <a>&#38;</a> Both are the single character &
<?xml version="1.0"?><a/> <a/> The declaration is not content

On a config file that has been through a formatter, or produced by a different library than last time, this is dozens of false positives you have to read past to find the one change that matters.

And the differences that are real

The opposite failure matters just as much. These pairs look nearly identical and are genuinely different:

Document A Document B The difference
<a>1</a> <a> 1 </a> Text content differs. Whitespace inside an element is significant unless a schema says otherwise
<a x="1"/> <a X="1"/> XML is case sensitive, in element and attribute names alike
<r><a/><b/></r> <r><b/><a/></r> Element order is significant, unlike attribute order

That third row is the asymmetry people find surprising. Attributes are an unordered set; child elements are an ordered sequence. A tool that treats both the same way is wrong about one of them.

The options, and when to change them

Option Default Turn it off when
Ignore attribute order On Practically never. The specification says order is insignificant. Off is for auditing a serialiser’s exact output.
Ignore whitespace between elements On You are checking that a formatter produced byte-identical indentation.
Ignore comments On Comments carry meaning in your workflow — build directives, for example.
Trim text content Off Your files are pretty-printed and you do not care about leading or trailing spaces inside elements.

The last one is off by default deliberately. XML says leaf whitespace is significant, so trimming it silently would be the same class of mistake this page exists to fix — just in the other direction.

Reading the paths

Every difference is located rather than merely counted.

Path Means
/catalog/title The title element inside catalog
/catalog/book[2] The second book element
/catalog/book[2]/@id The id attribute of that second book

The index only appears when there is more than one sibling with that name, so a unique element stays readable. The syntax is XPath-like on purpose — you can usually paste it straight into a query.

Worked example

Two exports of the same catalogue, one from a formatter and one raw:

A:  <catalog>
      <book id="1" lang="en">
        <title>Dune</title>
        <year>1965</year>
      </book>
    </catalog>

B:  <catalog>
    <book lang="en" id="1"><title>Dune</title><year>1966</year></book>
    </catalog>

A line-based text diff reports every line as changed — the indentation differs, the attributes are swapped, the elements are on one line instead of four.

This tool reports one difference:

/catalog/book/year   text content changed
    original: 1965
    changed:  1966

That is the whole argument for structural comparison. One real change, found without reading past nine false ones.

Parse errors

If either document is not well-formed you get the reason and the position, not a blank screen:

Input Reported as
<a></b> Closing tag </b> does not match <a>
<a> Unclosed tag <a>
<a/><b/> XML must have exactly one root element; found 2
<a x="1" x="2"/> Duplicate attribute x

The last one is worth knowing about. Duplicate attributes are forbidden by the XML specification, but several tools accept them silently and keep whichever came last — so a file can round-trip through them and lose data without complaint.

What this tool does not do

No three-way merge, no XSLT, no schema validation, no patch generation. Each of those is a separate job and bolting them on would turn a page you can use in ten seconds into one you have to learn.

It also does not resolve namespace prefixes. <ns:a xmlns:ns="urn:x"/> and <p:a xmlns:p="urn:x"/> are the same element to a namespace-aware processor, and this tool will report the prefixes as different. If that matters to your files, normalise the prefixes before comparing.

Related tools

The same argument applies to JSON, where key order is insignificant but array order is not — the JSON compare tool handles that asymmetry. For prose or code where you want to see the actual changed words, use text compare. To compare two sets of IDs or values rather than two documents, list compare gives all four set operations at once. And if a value is arriving mangled inside an attribute, the URL encoder will show you what percent-encoding did to it.

Frequently asked questions

Why not just use a text diff for XML?

Because it reports differences that are not there. Swap two attributes, reindent a file, or write <a/> instead of <a></a> and the document is unchanged, but a text diff flags every line involved. On a large config file that is dozens of false positives you have to read past to find the one real change.

Does attribute order matter in XML?

No. The XML specification is explicit that the order of attributes on an element is not significant, so <a x="1" y="2"/> and <a y="2" x="1"/> are the same element. This tool sorts attributes before comparing, which is why it reports them as identical.

Does element order matter?

Yes, and this is the opposite of attributes. The order of child elements is part of the document, so <r><a/><b/></r> and <r><b/><a/></r> are genuinely different. The tool compares children by position and will tell you an element was replaced.

Is whitespace significant in XML?

Between elements, usually not — it is indentation. Inside an element, yes: <a>1</a> and <a> 1 </a> have different text content, and absent a schema saying otherwise the difference is real. The tool ignores the first and reports the second, with an option to trim leaf text if your files are pretty-printed.

What do the paths in the results mean?

They locate each difference in the document. /catalog/book[2]/@id means the id attribute of the second book element inside catalog. The index only appears when there is more than one sibling with that name, so a unique element reads simply as /catalog/title.

Is my XML uploaded anywhere?

No. Both documents are parsed and compared by JavaScript in the page you are reading. There is no network request, no size limit imposed by us, and nothing is stored. Configuration files often contain hostnames and credentials, which is a good reason to check that claim on any tool you use.

Last updated: August 16, 2026