0

I am building a comparison engine script in PowerShell and one of the things I need to be able to compare are XML files. When I use the native PowerShell compare-object it returns 0 differences, yet if I grab the outerxml (text representation) and diff that I do get differences. Unfortunately this puts everything into one long string so is not useful.

I then tried using the XmlDiffPatch library from Microsoft, however if I use the sample program or the library within PowerShell, my 2 XML files fail with the exception:

$d.Compare("c:\scripts\ps\ref.xml", "c:\scripts\ps\tgt.xml", $false)
Exception calling "Compare" with "3" argument(s): "Length cannot be less than zero.
Parameter name: length"
At line:1 char:1
+ $d.Compare("c:\scripts\ps\ref.xml", "c:\scripts\ps\tgt.xml", $false)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentOutOfRangeException

Without access to the source code for this library I have no idea what is going on other than a bug. The 2 XML's parse fine in IE, so I know they are valid XML.

Has anyone else seen this before? How did you solve it?

David Buck
  • 3,752
  • 35
  • 31
  • 35
Justin
  • 1,303
  • 15
  • 30
  • Sorry, $d is the instantiation of the XmlDiffPatch class missed that line in the input. – Justin Apr 28 '15 at 03:22
  • I missed your comment, i will give this a try, in the end i ended up writing my own xml diff parser. It creates an xpath to every element in the xml document and then uses PS built-in compare to check each element and diff the attributes of each element. I also have an XSL i created that will convert a "diff" object (converted into xml) into a pretty html page which highlights the delta's in the various objects being compared. – Justin May 26 '15 at 03:06

4 Answers4

1

Here is a way I use it and a complete example for people who want to discover it :

# Test-xmldiffpatch.ps1
# This code need to download Microsoft tool
# https://msdn.microsoft.com/en-us/library/aa302294
# or Nuget
# https://www.nuget.org/packages/XMLDiffPatch/

# Load the external DLL
Add-Type -Path "C:\Program Files (x86)\XmlDiffPatch\Bin\xmldiffpatch.dll"

$xmlD1=[XML](Get-Content 'd:\temp\M1.xml')
$xmlD2=[XML](Get-Content 'd:\temp\M2.xml')
$xmlWriter = [System.Xml.XmlWriter]::Create("d:\temp\M3.xml")

$xmlDiff= New-Object Microsoft.XmlDiffPatch.XmlDiff
$xmlDiff.IgnorePrefixes=$true
$xmlDiff.IgnoreChildOrder=$true
$xmlDiff.IgnoreNamespaces=$true

$blIdentical = $xmldiff.Compare($xmlD1, $xmlD2, $xmlWriter);
$blIdentical
$xmlWriter.Close();

Where M1.xml and M2.xml are two similars or differents XML file M3.xml will receive the delta.

JPBlanc
  • 70,406
  • 17
  • 130
  • 175
1

Looks like XMLDiffPatch library has a bug in its method Microsoft.XmlDiffPatch.XmlDiff.NormalizeText(String text), which can't handle whitespace-only strings (" "). If you pass one, the method tries to instantiate a string of negative length, hence the exception.

Some of my XML's I was comparing contained attributes like AttributeName=" ", and they were causing these exceptions when the library tried to normalize them. I glanced over the XML spec, and attributes like this are not forbidden.

Turns out it can't be fixed, and there's no good workaround (except for 'fixing' XML prior to comparison). I ended up using XmlUnit.Net library instead.

  • I eventually gave up on this approach but good to know someone else ran into this. I eventually wrote my own xml diff script in powersell and will try to post it up later this week. – Justin Feb 23 '20 at 02:27
0

For Folks who come across this (like I did) source for XmlDiffPatch along with a fix for this issue is available here: - https://github.com/shadolight/XmlDiffPatch

Not my repo just looking for the same solution.

Rich Dominelli
  • 915
  • 1
  • 7
  • 18
0

The package to use in 2022+: https://www.nuget.org/packages/LovettSoftware.XmlDiff
Compatible with modern .NET versions (NETStandard2.0, NET6+, even .NET 4.5.2)

It's coming from the official Microsoft XmlNotepad repo

riskeez
  • 61
  • 4