Justin
Justin

Reputation: 1503

XmlDiffPatch raises exception Length cannot be less than zero

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?

Upvotes: 0

Views: 1062

Answers (4)

riskeez
riskeez

Reputation: 103

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

Upvotes: 0

Rich Dominelli
Rich Dominelli

Reputation: 915

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.

Upvotes: 0

Pavel Vorozheykin
Pavel Vorozheykin

Reputation: 11

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.

Upvotes: 1

JPBlanc
JPBlanc

Reputation: 72660

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.

Upvotes: 1

Related Questions