🌐
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')]
🌐
Oracle
docs.oracle.com › en › database › oracle › oracle-database › 26 › sqlrf › XMLDIFF.html
XMLDIFF
3 weeks ago - Previous Next JavaScript must be enabled to correctly display this content ... The XMLDiff function is the SQL interface for the XmlDiff C API. This function compares two XML documents and captures the differences in XML conforming to an Xdiff schema.
🌐
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.
🌐
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
🌐
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 ...
🌐
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%
🌐
Oracle
docs.oracle.com › en › database › oracle › oracle-database › 19 › adxdk › determining-XML-differences-using-C.html
Determining XML Differences Using C
XmlPatch can apply the differences captured from the comparison to other documents as specified by the application. XmlDiff compares the trees that represent two input documents, to determine their differences. Both input documents must use the same character-set encoding.
🌐
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%
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...

Find elsewhere
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

🌐
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%
🌐
GitHub
github.com › amra › XmlDiff
GitHub - amra/XmlDiff: XmlDiff produces an xml file with the difference between its two input xml files. It can receive a third optional xml file in which mandatory tags are specified, and those will be kept in the output xml file even if they were not changed.
When it doesn't replaces nor is replaced by other tags, it's change is reflected in the "mod" mark described above. Valid values are D(deleted) and N(new). ________________________________________________________________________________ xmlDiff.xml example: <?xml version="1.0" encoding="UTF-8"?> <book2 mod="C" myBook="yess" mod_myBook="C"> <person mod="C" h="5" mod_h="C"> <first mod="C" mand="y" ghhh="hey" mod_ghhh="D" hi="6" mod_hi="D" id="789" mod_id="D"> Bill </first> <last mod="C"> Paii </last> <first mod="N" mand="y"> William </first> </person> <animal mod="D" hi="4"> <first j="fg"> Fifia
Author   amra
🌐
NuGet
nuget.org › packages › LovettSoftware.XmlDiff
NuGet Gallery | LovettSoftware.XmlDiff 1.1.0
Generates difference files based on the comparison of two XML documents. This is a forked version of LovettSoftware.XmlDiff, which, in turn is based on XMLDiffPatch from Microsoft.
🌐
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); ...
🌐
Code Beautify
codebeautify.org › xml-diff
XML Diff
Any code can be removed without warning (if it is deemed offensive, damaging or for any other reason).
🌐
GitHub
github.com › JoshData › xml_diff
GitHub - JoshData/xml_diff: Compares two XML documents by diffing their text. · GitHub
Compares the text inside two XML documents and marks up the differences with <del> and <ins> tags.
Starred by 44 users
Forked by 10 users
Languages   Python
🌐
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.
🌐
PHP
pecl.php.net › package › xmldiff
PECL :: Package :: xmldiff
Search for in the Packages This site (using Google) Developers Developer mailing list SVN commits mailing list