31

I'm looking for a Windows-based diff tool that shows me the differences between two XML files, but does this tree-based, not line-based.
I.e. if a section has moved to a totally different place in the file it should not report differences.
These two files should be reported as 'the same':

<soapenv:Body>
  <mes:GetItem>
    <mes:ItemShape>
      <typ:BaseShape>IdOnly</typ:BaseShape>
      <typ:BodyType>Text</typ:BodyType>
      <typ:AdditionalProperties>
        <typ:FieldURI FieldURI="item:Subject" />
        <typ:FieldURI FieldURI="item:Categories" />
      </typ:AdditionalProperties>
    </mes:ItemShape>
    <mes:ItemIds>
      <typ:ItemId Id="AAMYAAA="/>
    </mes:ItemIds>
  </mes:GetItem>
</soapenv:Body>


<soapenv:Body>
  <mes:GetItem>
    <mes:ItemIds>
      <typ:ItemId Id="AAMYAAA="/>
    </mes:ItemIds>
    <mes:ItemShape>
      <typ:BodyType>Text</typ:BodyType>
      <typ:BaseShape>IdOnly</typ:BaseShape>
      <typ:AdditionalProperties>
        <typ:FieldURI FieldURI="item:Categories" />
        <typ:FieldURI FieldURI="item:Subject" />
      </typ:AdditionalProperties>
    </mes:ItemShape>
  </mes:GetItem>
</soapenv:Body>

And of course, all differences should be marked, preferably in a side-by-side view with indicators or lines connecting the sections that differ.

Free would be nice.
Optionaly ignoring name spaces would be nice.

11
  • 1
    Possible duplicate of Free XML Compare Tool
    – rrirower
    Mar 20, 2015 at 19:11
  • 3
    @rrirower yeah but it got closed there :/ Stack Exchange has this tendency of closing instead of migrating. Mar 21, 2015 at 2:19
  • Jan, have you tried the most common diff programs on Windows, such as WinMerge2011, to see if they have an option for that functionality? (Note that WinMerge2011 has many updates since the last update of regular WinMerge, even if the name implies the opposite.) Mar 21, 2015 at 23:56
  • 1
    "reported as 'the same'" ... These XML files are the "same" only true if you insist that the order of some tags is irrelevant. For some folks, the order does matter. You need a schema or some other signal to indicate which case, for which tags.
    – Ira Baxter
    Jun 24, 2015 at 18:04
  • 1
    @Mast My current work no longer needs this, so I have this on the back burner. Still plan to revisit this post though, when I can make some time.
    – user416
    Jul 23, 2018 at 7:22

6 Answers 6

9

Technically, XMLs are different

  • if they have whitespaces or not
  • if the order is different
  • if they have comments or not
  • if they have processing instructions or not
  • if their encoding is different
  • if their namespaces are different

but of course you can decide to ignore that or not, based on the semantic information an XML does not have.

Microsoft has developed the XML Diff and Patch tool for this purpose and you can integrate it in your own applications.

Note: the tool installs as "SQLXML Bulkload in .NET Code Sample" and comes with a Visual Studio solution XmlDiffView.sln that you need to compile yourself. Some basic programming knowledge in C# and Visual Studio Community Edition should be ok.

However, as mentioned in one of the answers on Stack Overflow, it has been compiled and made available on Bitbucket.

After that it comes with a UI that let's you choose the various XML comparison options:

XmlDiff UI

When I apply it to the 2 XMLs of your questions, it throws an exception. That is because of the namespaces which are not defined. After removing the namespaces, it says:

Files identical for the given options

4
  • 1
    Thanks. I have upvoted this answer but not marked it as the correct one. Reason: the interface of the results window of the GUI tool is horrible: when comparing two large XML files, the diff window is approx 3000 pixels wide, contains all identical XML, and has no scrollbars. Then try to find the differences between two 55 MB files ;-( I'm not a Cx programmer so I can't adapt the program.
    – user416
    Apr 3, 2017 at 12:16
  • @JanDoggen: yes, I agree, it's very developer-oriented. It can hardly be used without programming skills. Apr 3, 2017 at 12:23
  • @JanDoggen The scrollbar is a tiny sliver only a couple pixels wide at the right edge of the window. I agree the output isn't very pretty, but it is still a useful tool.
    – Suncat2000
    Aug 3, 2017 at 13:10
  • @ThomasWeller +1 for the link to BitBucket. I compiled, but had no luck, getting the original source working.
    – Suncat2000
    Aug 3, 2017 at 13:12
6

Focusing on the part that moved sections should be reported as no difference made me think of https://semanticmerge.com/, which doesn't compare XML-files, but C# and C code. And as it understand those languages it is able to display if code has moved and not changed.

This leads to an alternative approach for this question: Could it be possible to translate the XML into C# classes, and then do a semantic merge on the resulting code?

One possible approach, if this tool is not written already, could be to translate each and every element to classes, and each attribute (and body texts) to a string property within that class. If you want to ignore namespaces, then let your translator remove them in the translation process.

I translated the XML example given as proof of concept and got the following:

class soapenv__Body {
  class mes__GetItem {
    class mes__ItemShape {
      class typ__BaseShape {
          string body="IdOnly";
      }
      class typ__BodyType {
          string body="Textus";
      }
      class typ__AdditionalProperties {
        class typ__FieldURI  {
            string FieldURI="item:Subject";
        }
        class typ__FieldURI  {
            string FieldURI="item:Categories"; 
        }
      }
    }
    class mes__ItemIds {
      class typ__ItemId {
          string Id="AAMYAAA=";
      }
    }
  }
}

Then I switched the mes:ItemIds and mes:ItemShape and changed the text to Textus. Compared the following two files in Semantic Merge and got the following image:

Semantic Merge screenshot

In this image one can see the move, indicated by the M icon, and the change in text indicated by the C icon. Lines indicates where the different parts have moved/changed, and it possible to actually see the differences if they exist.

Note that Semantic Merge even though understanding C# code, isn't to strict on the identical class names of typ__FieldURI, which could be a nice features as XML can contain multiple nodes with the same name.

Summa summarum: Semantic Merge can correctly identify the XML as identical (or not) even though elements move, if you can convert the XML into a C# class structure.

1
  • Just for the fun of it, I tried moving the typ:FieldUri elements, and Semantic Merge correctly identified them as moved. So the order is correctly detected, and you can track order of attributes if so wanted.
    – holroy
    Jun 26, 2015 at 21:36
3

Technically those aren't the same (at least in xml), order does matter unless that is made explicit in the schema.

A combination of xmlstarlet and normal line-based utilities can make the problem much more tractable.

The following only compares the structure, but could be extended to look at the attributes,their values, and text

xmlstarlet el snippet1-with-namespaces.xml | sort > structure1.txt

xmlstarlet el snippet2-with-namespaces.xml | sort > structure2.txt

diff structure.txt structure2.txt

After running this on your snippets the diff shows no differences but there was some error text about namespaces (which would be safe to ignore).

2

I would recommend a tool XiMpLe which is primary the XML editor but it's also able to compare (and merge) xml files in a well arranged way. Your example is compared and evaluated as identical. There is also option to resolve namespaces as well.

Example of comparing result

0

Currently I am trying to solve a quite similar problem for myself. Unfortunately I did not find any library thats suits my needs to produce a svg visualization of an xml comparison.

Therefore I started an open source library inspired by the X-Diff algorithm. So just for fun and in the hope to find someone supporting the XmlXdiff library. Till now it is not a bullet prove library and still under construction but here is the result for your example snippet:

enter image description here

Code producing this result:

    from XmlXdiff.XReport import DrawXmlDiff

    _xml1 = """<frame xmlns:soapenv="sn" xmlns:mes="meas" xmlns:typ="type">
    <soapenv:Body>
      <mes:GetItem>
        <mes:ItemShape>
          <typ:BaseShape>IdOnly</typ:BaseShape>
          <typ:BodyType>Text</typ:BodyType>
          <typ:AdditionalProperties>
            <typ:FieldURI FieldURI="item:Subject" />
            <typ:FieldURI FieldURI="item:Categories" />
          </typ:AdditionalProperties>
        </mes:ItemShape>
        <mes:ItemIds>
          <typ:ItemId Id="AAMYAAA="/>
        </mes:ItemIds>
      </mes:GetItem>
    </soapenv:Body>
    </frame>"""
    _xml2 = """<frame xmlns:soapenv="sn" xmlns:mes="meas" xmlns:typ="type">
    <soapenv:Body>
      <mes:GetItem>
        <mes:ItemIds>
          <typ:ItemId Id="AAMYAAA="/>
        </mes:ItemIds>
        <mes:ItemShape>
          <typ:BodyType>Text</typ:BodyType>
          <typ:BaseShape>IdOnly</typ:BaseShape>
          <typ:AdditionalProperties>
            <typ:FieldURI FieldURI="item:Categories" />
            <typ:FieldURI FieldURI="item:Subject" />
          </typ:AdditionalProperties>
        </mes:ItemShape>
      </mes:GetItem>
    </soapenv:Body>
    </frame>"""

    _path1 = '{}\\..\\..\\tests\\simple\\xml1.xml'.format(getPath())
    _path2 = '{}\\..\\..\\tests\\simple\\xml2.xml'.format(getPath())
    _out = '{}\\..\\..\\tests\\simple\\xdiff.svg'.format(getPath())

    with open(_path1, "w") as f:
        f.write(_xml1)

    with open(_path2, "w") as f:
        f.write(_xml2)

    x = DrawXmlDiff(_path1, _path2)
    x.draw()
    x.saveSvg(_out)
0

To summarise, addressing your requirements:

  1. Structurally aware, not line-based comparison: Yes
  2. Can run on Windows: Yes
  3. Orderless Comparison/Move Handling: Yes
  4. Side-by-Side comparison output: Yes
  5. Ignoring expected changes: Yes
  6. Free: No, but a free trial is available.

XML Compare, developed by DeltaXML, is a structurally aware XML Comparison tool that can be run on Windows, as well as Linux and Mac, using Java. XML Compare can be used via command line, REST API, and Java API.

XML Compare's diff outputs are valid XML, meaning that they can be readily processed by other applications, and into other output formats via post-processing configuration. Changes are identified by the addition of new attributes in the diff output that indicate whether the content or structure was present in the A input, present in the B input, and if it is the same in both or has changed. It follows a simple "A!=B" format, see the example snippet below.

<height deltaxml:deltaV2="A!=B">
           <deltaxml:textGroup deltaxml:deltaV2="A!=B">
              <deltaxml:text deltaxml:deltaV2="A">up to 1.4 meters</deltaxml:text>
              <deltaxml:text deltaxml:deltaV2="B">up to 1.3 meters</deltaxml:text>
           </deltaxml:textGroup>
        </height>

Regarding your requirement for accounting for content that has moved, XML Compare is highly configurable. There are dozens of pre-configured input and output processors and filters, and custom pipelines and filters can be created using XSLT.

Specific to your requirements there are pre-configured facilities for Comparing Orderless Elements in the case of comparing where the order of elements is not significant, Detecting and Handling Moves, and Ignoring Changes where they are expected and do not need to be highlighted.

Finally, one of pre-configured output formats available is a side-by-side HTML diff report which is built on the delta output. In cases where you need a more specific output however, you can again configure and process the output using XSLT or the existing configuration options. Below is a screenshot of the side-by-side diff report:

DeltaXML side by side HTML diff report

Disclosure: I am an employee of DeltaXML.

1
  • As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Oct 14, 2022 at 19:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy