XML Diff: Compare Two XML Files Online
Paste, format, and compare two XML documents side-by-side. Pretty-print, validation, and namespace-aware highlighting built in.
What is the XML diff tool?
A free, in-browser tool for comparing two XML documents. Paste an old pom.xml on the left, the new one on the right, and the changes light up element by element. Nothing leaves your machine.
The diff itself is character-level, and validation goes through the browser's native DOMParser. The Format button on each pane reflows your XML with consistent indentation. Live validation flags malformed markup, mismatched tags, and broken entity references as you type.
If you have ever opened a 4,000-line Spring application context in a code review and tried to find the one bean whose class attribute changed, this is the tool that gets you there in seconds. For plain prose, our text diff tool is the right pick. For structured data with key/value pairs, JSON diff handles object reordering more cleanly than XML can.
How the diff actually works
The diff runs at the character level, then a semantic post-processing pass shifts the highlights so they land on tag names, attributes, and text content rather than random punctuation. Insertions show in green on the right pane, deletions in red on the left.
XML has a few quirks the spec calls out, and they all bite when you compare two files as text. The XML 1.0 specification says attribute order on an element is not significant, so <img src="a.png" alt="x"/> and <img alt="x" src="a.png"/> are the same to a parser. A text diff will still flag the swap. There is no fix for this short of a structural compare; the practical workaround is to format both sides with the same tool so attribute order stays stable.
Namespaces add another layer. Two documents that bind the same URI to different prefixes are equivalent under Namespaces in XML 1.0, but a text diff will paint every ns1: vs ns2: swap as a change. Format both sides, fix the prefix in one of them, then re-diff. For a transformation pipeline that normalises namespaces and attribute order before diffing, look at XSLT 3.0 or a canonicalisation step per Canonical XML.
How to compare XML in three steps
Two text panes, one diff. There is no signup, no upload, no server round-trip.
- 1
Paste or upload your XML
Paste the old XML on the left, the new XML on the right. Or click Upload on either side to load a .xml, .pom, .config, or .svg file directly. The Sample button fills both panes with a small pom.xml example if you want to see the tool in action first.
- 2
Format both sides for a fair comparison
Click Format on each pane to pretty-print with consistent indentation and line breaks. This normalises whitespace so the diff highlights real content changes, not formatting noise from a Windows CRLF file vs a Unix LF file. The validation badge turns green when DOMParser accepts your document as well-formed.
- 3
Read the diff
Deletions appear with a red highlight on the left, insertions with a green highlight on the right. Scroll either side and the other follows. The change counts in each header tell you how many distinct edits the diff found across element names, attribute values, and text content.
When XML diff is the right tool
Reviewing pom.xml dependency upgrades
A Dependabot PR bumps fifteen Maven coordinates at once. Paste the old pom.xml against the new one to confirm the actual upgrades: spring-boot-starter-web moved from 3.1.5 to 3.2.1, jackson-databind from 2.15.3 to 2.16.0, and a new micrometer-registry-prometheus dependency was added. The diff makes the version bumps obvious so you can sanity-check the changelog before approving.
Diffing Spring application context XML
When a service starts failing after a refactor, the cause is often a single bean whose class attribute or constructor argument changed in applicationContext.xml. Paste the working revision against HEAD; the diff surfaces the swapped class="com.acme.OldDataSource" vs class="com.acme.HikariDataSource" instantly, and the surrounding <property> tags tell you what configuration moved with it.
Comparing SOAP request and response bodies
A SOAP integration that worked yesterday returns a Fault today. Capture both envelopes from your packet logger or WireMock recordings, drop them into the diff, and the offending element jumps out: a <currencyCode> that switched from USD to a missing element, or a namespace declaration on the soap:Envelope that the upstream service quietly changed. Without a side-by-side view, finding this in 800 lines of XML is hopeless.
Auditing AndroidManifest.xml permissions
Before shipping a release, diff AndroidManifest.xml against the previous tag to catch permission creep. A new <uses-permission android:name="android.permission.READ_CONTACTS"/> that snuck in with a third-party SDK update is exactly the kind of thing the Play Store will flag at review time. The diff also surfaces changes to <intent-filter> elements and android:exported flags, which are common security review focus areas.
Tracking RSS or Atom feed schema changes
A feed reader breaks because the source switched from RSS 2.0 to Atom 1.0, or a publisher added a new <media:thumbnail> namespace. Save a snapshot of the working feed, diff it against the live one, and the structural change shows up in seconds. Same workflow for OPML imports and podcast feeds where the channel-level metadata moved between elements.
OOXML document.xml diffs
A .docx is just a zip with XML inside. Unzip both versions of a contract, run a diff on word/document.xml, and you see the actual text edits without Word's tracked-changes markup getting in the way. Useful when a paralegal sends back a "clean" copy that supposedly matches a redline; the XML tells you which paragraph elements moved and which run-level formatting changed.
XML quick reference
A short cheat sheet for the parsing edge cases this tool surfaces most often. All of it is grounded in the W3C XML specifications.
| Topic | What this tool does |
|---|
| Attribute order | Not significant per the XML 1.0 spec. <a x="1" y="2"/> equals <a y="2" x="1"/> to a parser. A text diff will flag the swap; format both sides to keep order stable. |
|---|
| Namespaces | URI-bound, prefix-aliased. Two documents binding the same URI to different prefixes are equivalent. See Namespaces in XML 1.0. |
|---|
| CDATA sections | Literal text wrapped in <![CDATA[ ... ]]>. The parser does not interpret tags or entities inside. The sequence ]]> cannot appear inside a CDATA block. |
|---|
| Mixed content | Elements may contain text, child elements, and whitespace in any order. <p>Hello <b>world</b>!</p> is mixed content and whitespace there is significant. |
|---|
| Comments | <!-- comment -->. Cannot contain -- internally. Stripped by most processors but preserved as text in this diff. |
|---|
| Encoding and BOM | Declared via <?xml version="1.0" encoding="UTF-8"?>. UTF-8 BOM is a hidden first character; common cause of phantom one-character diffs at line 1. |
|---|
| XML 1.0 vs 1.1 | Almost everyone uses XML 1.0. Version 1.1 adds support for additional Unicode control characters in element content; rarely seen in the wild. |
|---|
| Entity references | Five built-ins: & < > ' ". Numeric character references like é for accented letters are also valid. Self-closing <br/> and explicit <br></br> are equivalent. |
|---|
XML diff: frequently asked questions
Will XML attribute reordering or whitespace show up as a diff?
Yes, both will. A text diff compares characters line by line, so reformatting, attribute reordering, or whitespace inside elements all show up as differences even when the document is logically identical. Click Format on both panes first and the diff focuses on real content changes. For element trees with deeply nested children, a structural compare via XSLT or Canonical XML is the next step up; this tool handles 95% of practical XML reviews without that complexity.
Does the order of attributes on an element matter?
No, not to an XML parser. The XML 1.0 spec says attribute order is not significant, so <img src="a.png" alt="x"/> and <img alt="x" src="a.png"/> represent the same element. A character diff will still flag the reorder because it sees the raw text. The fix is to format both sides with the same tool so attribute order is consistent before diffing, or to apply Canonical XML normalisation if you control the pipeline.
How do XML namespaces affect the diff?
Namespaces are URI-based, but you bind them to short prefixes in the document. Two files that bind http://maven.apache.org/POM/4.0.0 to different prefixes are equivalent under the Namespaces in XML spec, but the text diff will mark every prefix swap as a change. The practical workaround is to format both files and use matching prefixes on both sides. For automated pipelines, a Canonical XML pass normalises this away.
Can I diff XML files with CDATA sections?
Yes. CDATA sections are just text content with the XML parser told not to interpret it, so <![CDATA[<b>raw</b>]]> compares as the literal characters inside. Long CDATA blocks (script tags, embedded HTML, SQL) diff cleanly. The one gotcha is that you cannot have ]]> inside a CDATA section; if your data contains that sequence, the source must split it across two CDATA blocks, which the diff will show as written.
Should I use XSLT instead of a diff?
Use XSLT when you want to transform XML or normalise it before comparing (sort children, drop comments, canonicalise namespaces). Use this diff when you want to see what changed between two specific files. The two are complementary: an XSLT pre-pass plus this diff is a strong workflow for noisy machine-generated XML. For most code-review use cases (pom.xml, AndroidManifest, application context), the diff alone is enough.
Does the encoding declaration or BOM affect comparison?
A bit. The <?xml version="1.0" encoding="UTF-8"?> declaration is part of the document text, so swapping UTF-8 for UTF-16 shows as a one-line diff. A UTF-8 byte order mark (BOM) at the very start is a single hidden character that some editors strip and others preserve, which is a common source of phantom diffs. If two files look identical but the diff shows a change at line 1 character 0, suspect the BOM and re-save with a known encoding setting.
Why do my SOAP envelopes diff weirdly when I rename a namespace prefix?
Because text diff is namespace-blind. Renaming xmlns:soap to xmlns:s and updating every <soap:Body> to <s:Body> is a no-op to an XML parser; the bound URI is unchanged and the document is logically identical. The character diff sees every tag as different and lights up the page. The fix is to canonicalise both sides before diffing. XML Canonicalization (C14N, RFC 3076) is the spec used by XML signatures specifically to handle this. Tools like xmllint --c14n or xmlstarlet c14n produce a canonical form that survives prefix renames.
Privacy and how this works
Your XML never leaves your browser. The parser, formatter, and diff all run on your machine, locally. No analytics on your input, no logs, no "helpful" cloud round-trip. Parsing and validation use the browser's native DOMParser, and the spec we follow is W3C XML 1.0. Background reading on the format itself is on Wikipedia.