🌐
GitHub
github.com › Shoobx › xmldiff
GitHub - Shoobx/xmldiff: A library and command line utility for diffing xml
xmldiff is a library and a command-line utility for making diffs out of XML. This may seem like something that doesn't need a dedicated utility, but change detection in hierarchical data is very different from change detection in flat data.
Starred by 226 users
Forked by 53 users
Languages   Python 98.7% | Python 98.7%
🌐
PyPI
pypi.org › project › xmldiff
xmldiff · PyPI
xmldiff is a library and a command-line utility for making diffs out of XML. This may seem like something that doesn’t need a dedicated utility, but change detection in hierarchical data is very different from change detection in flat data.
      » pip install xmldiff
    
Published   May 13, 2024
Version   2.7.0
🌐
SemanticDiff
semanticdiff.com › online-diff › xml
SemanticDiff - Compare XML Online
Compare two XML files in your browser using our free semantic diff tool. See how values and attributes differ while ignoring formatting changes.
🌐
GitHub
github.com › rpeyron › libxmldiff
GitHub - rpeyron/libxmldiff: a simple library to diff XML files
(c) 2004-2006 - Rémi Peyronnet Syntax : xmldiff action [options] <parameters> Actions - diff <before.xml> <after.xml> <output.xml> - merge <before.xml> <after.xml> <output.xml> - xslt <style.xsl> <input.xml> <output.xml> [param='value'] - recalc <before.xml> <after.xml> - execute <script.xds> (xds = list of these commands) - load <filename> <alias> - save <filename> <alias> - close <alias> / discard <alias> (same as close without saving) - flush - options - print <string> - delete <from alias> <xpath expression> - dup(licate) <source alias> <dest alias> - rem(ark),#,--,;,// <remark> - print_c
Starred by 11 users
Forked by 6 users
Languages   C++ 59.4% | Makefile 33.8% | Shell 2.6% | Batchfile 1.3% | M4 1.1% | C 1.0% | C++ 59.4% | Makefile 33.8% | Shell 2.6% | Batchfile 1.3% | M4 1.1% | C 1.0%
🌐
Readthedocs
xmldiff.readthedocs.io › en › stable › commandline.html
Command-line Usage — xmldiff documentation
By default xmldiff will strip all whitespace that is between tags, as opposed to inside tags. That whitespace isn’t a part of any data and can be ignored.
🌐
TextCompare
textcompare.org › xml
Online Xml Compare Tool
Find difference between 2 text files. Just input or paste original and modified text and click Compare button. Fast, Private & Unlimited.
🌐
GitHub
github.com › BrutalSimplicity › XmlDiffLib
GitHub - BrutalSimplicity/XmlDiffLib: Library for finding the differences between two Xml files.
var exampleA = File.ReadAllText(@"C:\Users\KTaborn\Documents\repos\XmlDiffLib\XmlDiffLib.Tests\Resources\exampleA.xml"); var exampleB = File.ReadAllText(@"C:\Users\KTaborn\Documents\repos\XmlDiffLib\XmlDiffLib.Tests\Resources\exampleB.xml"); var diff = new XmlDiff(exampleA, exampleB); diff.CompareDocuments(new XmlDiffOptions() { TwoWayMatch = true });
Starred by 34 users
Forked by 16 users
Languages   C# 100.0% | C# 100.0%
Find elsewhere
🌐
CoreFiling
corefiling.com › home › open source tools › xml comparison tool
Free Online XML Comparison Tool
June 20, 2025 - CoreFiling XML Differences uses XML Pretty Printer and diff to display differences between XML files in an easy-to-read format.
🌐
Minifier
minifier.org › xml-compare
Minify JS and CSS online, or include the minifier in your project for on-the-fly compression.
Quickly compare XML files online. Highlight differences in structure, tags, and values with our XML Compare tool. Simplify file validation and save time!
🌐
Readthedocs
xmldiff.readthedocs.io › en › stable › advanced.html
Advanced Usage — xmldiff documentation
One common use case for this is to have more intelligent text handling. The standard formatters will treat any text as just a value, and the resulting diff will simply replace one value with another: >>> from xmldiff import main, formatting >>> left = '<body><p>Old Content</p></body>' >>> right = '<body><p>New Content</p></body>' >>> main.diff_texts(left, right) [UpdateTextIn(node='/body/p[1]', text='New Content')]
🌐
Readthedocs
xmldiff.readthedocs.io
xmldiff — xmldiff documentation
xmldiff is a library and a command-line utility for making diffs out of XML. This may seem like something that doesn’t need a dedicated utility, but change detection in hierarchical data is very different from change detection in flat data. XML type formats are also not only used for computer ...
Top answer
1 of 1
26

After a couple days of messing around, I found a solution that I think works for me. Maybe it could work for other people as well.

The MS XML Diff and Patch tool was a viable option. When you Diff first file against the second file it creates an XML "DiffGram" listing what changes it detected between the two XML files.

To take care of all 3 rules that I listed above, I Diff'd the two files in one direction, then opened the DiffGram file using Linq-to-XML and Removed all the "Add" and "Remove" lines.

XNamespace xd = "http://schemas.microsoft.com/xmltools/2002/xmldiff";
var doc = XDocument.Load(_diffGramFile);
doc.Root.DescendantsAndSelf(xd + "add").Remove();
doc.Root.DescendantsAndSelf(xd + "remove").Remove();

Then I patched up (merged) this edited diffgram against the first file and created a partially merged temporary file. This takes care of Rules 1 and 2.

Next, I Diff'd the partially merged file against the first file used. Then opened the new DiffGram and removed all Change references to "UseExistingValue".

var newdoc = XDocument.Load(_diffGramFile);
newdoc.Root.DescendantsAndSelf(xd + "change")
      .Where(x => x.Value == "UseExistingValue").Remove();

And merged this edited DiffGram against the partially merged file which takes care of Rule 3. Saving this out to XML then produces the final XML merged according to the rules defined above.

Hopefully this can help out other people.

HINT: After installing the XmlDiffPatch library, the XmlDiffPatch DLL can be found in C:\Windows\assembly\GAC\XmlDiffPatch\1.0.8.28__b03f5f7f11d50a3a\XmlDiffPatch.dll

🌐
Oracle
docs.oracle.com › en › database › oracle › oracle-database › 26 › sqlrf › XMLDIFF.html
XMLDIFF
3 weeks ago - Oracle XML Developer's Kit Programmer's Guide for more information on using this function, including examples, and Oracle Database XML C API Reference for information on the XML APIs for C ... SELECT XMLDIFF( XMLTYPE('<?xml version="1.0"?> <bk:book xmlns:bk="http://example.com"> <bk:tr> <bk:td> <bk:chapter> Chapter 1.
Top answer
1 of 2
11

There are two immediate solutions:

Solution 1.

You can first apply a simple transform to the two documents that will delete the elements that should not be compared. Then, compare the results ing two documents -- exactly with your current code. Here is the transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="Name|Team|Pos"/>
</xsl:stylesheet>

When this transformation is applied to the provided XML document:

<Stats Date="2011-01-01">
    <Player Rank="1">
        <Name>Sidney Crosby</Name>
        <Team>PIT</Team>
        <Pos>C</Pos>
        <GP>39</GP>
        <G>32</G>
        <A>33</A>
        <PlusMinus>20</PlusMinus>
        <PIM>29</PIM>
        <PP>10</PP>
        <SH>1</SH>
        <GW>3</GW>
        <Shots>0</Shots>
        <ShotPctg>154</ShotPctg>
        <TOIPerGame>20.8</TOIPerGame>
        <ShiftsPerGame>21:54</ShiftsPerGame>
        <FOWinPctg>22.6</FOWinPctg>
    </Player>
</Stats>

the wanted resulting document is produced:

<Stats Date="2011-01-01">
   <Player Rank="1">
      <GP>39</GP>
      <G>32</G>
      <A>33</A>
      <PlusMinus>20</PlusMinus>
      <PIM>29</PIM>
      <PP>10</PP>
      <SH>1</SH>
      <GW>3</GW>
      <Shots>0</Shots>
      <ShotPctg>154</ShotPctg>
      <TOIPerGame>20.8</TOIPerGame>
      <ShiftsPerGame>21:54</ShiftsPerGame>
      <FOWinPctg>22.6</FOWinPctg>
   </Player>
</Stats>

Solution 2.

This is a complete XSLT 1.0 solution (for convenience only, the second XML document is embedded in the transformation code):

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vrtfDoc2">
  <Stats Date="2011-01-01">
    <Player Rank="2">
        <Name>John Smith</Name>
        <Team>NY</Team>
        <Pos>D</Pos>
        <GP>38</GP>
        <G>32</G>
        <A>33</A>
        <PlusMinus>15</PlusMinus>
        <PIM>29</PIM>
        <PP>10</PP>
        <SH>1</SH>
        <GW>4</GW>
        <Shots>0</Shots>
        <ShotPctg>158</ShotPctg>
        <TOIPerGame>20.8</TOIPerGame>
        <ShiftsPerGame>21:54</ShiftsPerGame>
        <FOWinPctg>22.6</FOWinPctg>
    </Player>
  </Stats>
 </xsl:variable>

 <xsl:variable name="vDoc2" select=
  "document('')/*/xsl:variable[@name='vrtfDoc2']/*"/>

 <xsl:template match="node()|@*" name="identity">
  <xsl:param name="pDoc2"/>
  <xsl:copy>
   <xsl:apply-templates select="node()|@*">
    <xsl:with-param name="pDoc2" select="$pDoc2"/>
   </xsl:apply-templates>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="/">
  <xsl:apply-templates select="*">
   <xsl:with-param name="pDoc2" select="$vDoc2"/>
  </xsl:apply-templates>

  -----------------------

  <xsl:apply-templates select="$vDoc2">
   <xsl:with-param name="pDoc2" select="/*"/>
  </xsl:apply-templates>
 </xsl:template>

 <xsl:template match="Player/*">
  <xsl:param name="pDoc2"/>
  <xsl:if test=
   "not(. = $pDoc2/*/*[name()=name(current())])">
   <xsl:call-template name="identity"/>
  </xsl:if>
 </xsl:template>

 <xsl:template match="Name|Team|Pos" priority="20"/>
</xsl:stylesheet>

when this transformation is applied on the same first document as above, the correct diffgrams are produced:

<Stats Date="2011-01-01">
   <Player Rank="1">
      <GP>39</GP>
      <PlusMinus>20</PlusMinus>
      <GW>3</GW>
      <ShotPctg>154</ShotPctg>
   </Player>
</Stats>

  -----------------------

  <Stats xmlns:xsl="http://www.w3.org/1999/XSL/Transform" Date="2011-01-01">
   <Player Rank="2">
      <GP>38</GP>
      <PlusMinus>15</PlusMinus>
      <GW>4</GW>
      <ShotPctg>158</ShotPctg>
   </Player>
</Stats>

How this works:

  1. The transformation is applied on the first document, passing the second document as parameter.

  2. This produces an XML document whose only leaf element nodes are the ones that have different value than the corresponding leaf element nodes in the second document.

  3. The same processing is performed as in 1. above, but this time on the second document, passing the first document as parameter.

  4. This produces a second diffgram: an XML document whose only leaf element nodes are the ones that have different value** than the corresponding leaf element nodes in the first document

2 of 2
2

Okay... I finally opted with a pure C# solution to compare the two XML files, without using the XML Diff/Patch .dll and without even needing to use XSL transforms. I will be needing XSL transforms in the next step though, to convert the Xml into HTML for viewing purposes, but I have figured an algorithm using nothing but System.Xml and System.Xml.XPath.

Here is my algorithm:

private void CompareXml(string file1, string file2)
{
    // Load the documents
    XmlDocument docXml1 = new XmlDocument();
    docXml1.Load(file1);
    XmlDocument docXml2 = new XmlDocument();
    docXml2.Load(file2);


    // Get a list of all player nodes
    XmlNodeList nodes1 = docXml1.SelectNodes("/Stats/Player");
    XmlNodeList nodes2 = docXml2.SelectNodes("/Stats/Player");

    // Define a single node
    XmlNode node1;
    XmlNode node2;

    // Get the root Xml element
    XmlElement root1 = docXml1.DocumentElement;
    XmlElement root2 = docXml2.DocumentElement;

    // Get a list of all player names
    XmlNodeList nameList1 = root1.GetElementsByTagName("Name");
    XmlNodeList nameList2 = root2.GetElementsByTagName("Name");

    // Get a list of all teams
    XmlNodeList teamList1 = root1.GetElementsByTagName("Team");
    XmlNodeList teamList2 = root2.GetElementsByTagName("Team");

    // Create an XmlWriterSettings object with the correct options. 
    XmlWriter writer = null;
    XmlWriterSettings settings = new XmlWriterSettings();
    settings.Indent = true;
    settings.IndentChars = ("  ");
    settings.OmitXmlDeclaration = false;

    // Create the XmlWriter object and write some content.
    writer = XmlWriter.Create(StatsFile.XmlDiffFilename, settings);
    writer.WriteStartElement("StatsDiff");


    // The compare algorithm
    bool match = false;
    int j = 0;

    try 
    {
        // the list has 500 players
        for (int i = 0; i < 500; i++)
        {
            while (j < 500 && match == false)
            {
                // There is a match if the player name and team are the same in both lists
                if (nameList1.Item(i).InnerText == nameList2.Item(j).InnerText)
                {
                    if (teamList1.Item(i).InnerText == teamList2.Item(j).InnerText)
                    {
                        match = true;
                        node1 = nodes1.Item(i);
                        node2 = nodes2.Item(j);
                        // Call to the calculator and Xml writer
                        this.CalculateDifferential(node1, node2, writer);
                        j = 0;
                    }
                }
                else
                {
                    j++;
                }
            }
            match = false;

        }
        // end Xml document
        writer.WriteEndElement();
        writer.Flush();
    }
    finally
    {
        if (writer != null)
            writer.Close();
    }
}

XML Results:

<?xml version="1.0" encoding="utf-8"?>
<StatsDiff>    
  <Player Rank="1">
    <Name>Sidney Crosby</Name>
    <Team>PIT</Team>
    <Pos>C</Pos>
    <GP>0</GP>
    <G>0</G>
    <A>0</A>
    <Points>0</Points>
    <PlusMinus>0</PlusMinus>
    <PIM>0</PIM>
    <PP>0</PP>
    <SH>0</SH>
    <GW>0</GW>
    <OT>0</OT>
    <Shots>0</Shots>
    <ShotPctg>0</ShotPctg>
    <ShiftsPerGame>0</ShiftsPerGame>
    <FOWinPctg>0</FOWinPctg>
  </Player>

  <Player Rank="2">
    <Name>Steven Stamkos</Name>
    <Team>TBL</Team>
    <Pos>C</Pos>
    <GP>1</GP>
    <G>0</G>
    <A>0</A>
    <Points>0</Points>
    <PlusMinus>0</PlusMinus>
    <PIM>2</PIM>
    <PP>0</PP>
    <SH>0</SH>
    <GW>0</GW>
    <OT>0</OT>
    <Shots>4</Shots>
    <ShotPctg>-0,6000004</ShotPctg>
    <ShiftsPerGame>-0,09999847</ShiftsPerGame>
    <FOWinPctg>0,09999847</FOWinPctg>
  </Player>
[...]
</StatsDiff>

I have spared to show the implementation for the CalculateDifferential() method, it is rather cryptic but it is fast and efficient. This way I could obtain the results wanted without using any other reference but the strict minimum, without having to use XSL...

🌐
Xlcompare
xlcompare.com › compare-xml-files.html
Compare XML Files Online. Free. No Upload. Get the Semantic XML diffs.
October 3, 2009 - Compare two XML docs and get the difference online. Drop your files on this page and get the highlighted diffs. Get semantic XML differences by comparing XML documents with key nodes and attributes.
🌐
ExtendsClass
extendsclass.com › xml-diff.html
XML diff - Compare xml online
It can be helpful to compare XML documents, unfortunately it can be difficult to see the differences between large XML documents. This free online tool will allows you to do this easily.
🌐
Stack Overflow
stackoverflow.com › questions › 57671467 › c-understanding-and-consuming-xmldiff-difference-file
c#: Understanding and consuming XMLDiff difference-File - Stack Overflow
Now I want to get all the changes in the XML and list them in a Collection: I tried it with using XDocument and iterating through the nodes but I dont really understand the match-attribute in here. XDocument xmlDifffDoc = XDocument.Load(reader); ...
🌐
UW Computer Sciences
pages.cs.wisc.edu › ~yuanwang › xdiff.html
X-Diff: An XML Diff Tool
X-Diff is a tool for detecting the difference between two XML documents. It was originally developed in the Niagara Query Engine · Unlike other xml diff tools, X-Diff uses an unordered model (only ancestor relationships are significant) to compute difference between two XML documents, which ...