(view source code of comparesitemaps.cs as plain text)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Xml;
namespace RobvanderWoude{internal class CompareSitemaps
{static readonly string progver = "1.00";
static int Main( string[] args )
{int rc = 0;
bool quiet = false;
bool verbose = false;
Stopwatch stopwatch = new Stopwatch( );
#region Command Line Parsingif ( args.Length < 2 || args.Length > 3 )
{return ShowHelp( );
}if ( args.Length == 3 )
{if ( args[2].ToUpper( ) == "/V" )
{verbose = true;
}else if ( args[2].ToUpper( ) == "/Q" )
{quiet = true;
} else {return ShowHelp( );
} }if ( !File.Exists( args[0] ) )
{return ShowHelp( "File \"{0}\" not found", args[0] );
}if ( !File.Exists( args[1] ) )
{return ShowHelp( "File \"{0}\" not found", args[1] );
}if ( !QuickTestXML( args[0] ) )
{return ShowHelp( "File \"{0}\" is not an XML file", args[0] );
}if ( !QuickTestXML( args[1] ) )
{return ShowHelp( "File \"{0}\" is not an XML file", args[1] );
} #endregion Command Line Parsingif ( verbose )
{stopwatch.Start( );
} #region Open XMLXmlReader xml0r = XmlReader.Create( args[0] );
XmlDocument xml0d = new XmlDocument( );
xml0d.Load( xml0r );
XmlReader xml1r= XmlReader.Create( args[1] );
XmlDocument xml1d = new XmlDocument( );
xml1d.Load( xml1r );
int nodecount0 = xml0d.DocumentElement.ChildNodes.Count;
int nodecount1 = xml1d.DocumentElement.ChildNodes.Count;
if ( nodecount0 != nodecount1 )
{rc = 1;
if ( quiet )
{return 1;
} } #endregion Open XMLif ( verbose )
{Single filesize0 = new FileInfo( args[0] ).Length / 1048576;
Single filesize1 = new FileInfo( args[1] ).Length / 1048576;
Console.WriteLine( "Files to compare:" );
Console.WriteLine( "=================" );
Console.WriteLine( "{0,5:0.00} MB {1,7} nodes {2}", filesize0, nodecount0, Path.GetFullPath( args[0] ) );
Console.WriteLine( "{0,5:0.00} MB {1,7} nodes {2}", filesize1, nodecount1, Path.GetFullPath( args[1] ) );
Console.WriteLine( );
} #region Read XMLSortedList<string, string> urls = new SortedList<string, string>( );
SortedList<string, string> urls0 = new SortedList<string, string>( );
SortedList<string, string> urls1 = new SortedList<string, string>( );
for ( int i = 0; i < nodecount0; i++ )
{string url = xml0d.DocumentElement.ChildNodes[i].ChildNodes[0].InnerText;
string lastmod = xml0d.DocumentElement.ChildNodes[i].ChildNodes[1].InnerText;
urls[url] = url;
urls0[url] = lastmod;
}for ( int i = 0; i < nodecount1; i++ )
{string url = xml1d.DocumentElement.ChildNodes[i].ChildNodes[0].InnerText;
string lastmod = xml1d.DocumentElement.ChildNodes[i].ChildNodes[1].InnerText;
urls[url] = url;
urls1[url] = lastmod;
}xml0r.Close( );
xml1r.Close( );
#endregion Read XMLConsole.ForegroundColor = ConsoleColor.Black;
Console.BackgroundColor = ConsoleColor.White;
int width = Console.WindowWidth;
Console.WriteLine( new String( ' ', width - 1 ) );
Console.WriteLine( "Sitemap0: Sitemap1: URL:{0}", new string( ' ', width - 33 ) );
Console.WriteLine( new String( ' ', width - 1 ) );
Console.ResetColor( );
Console.WriteLine( );
ConsoleColor defcol = Console.ForegroundColor;
ConsoleColor lm0col = defcol;
ConsoleColor lm1col = defcol;
ConsoleColor urlcol = defcol;
for ( int i = 0; i < urls.Keys.Count; i++ )
{string url = urls.Keys[i];
string lastmod0 = string.Empty;
string lastmod1 = string.Empty;
if ( urls0.ContainsKey( url ) )
{lastmod0 = urls0[url];
}if ( urls1.ContainsKey( url ) )
{lastmod1 = urls1[url];
}if ( verbose || lastmod0 != lastmod1 )
{if ( lastmod0 != lastmod1 )
{rc = 1;
if ( quiet )
{return 1;
}if ( string.IsNullOrWhiteSpace( lastmod0 ) ) // url in second sitemap only
{lm1col = ConsoleColor.Red;
urlcol = ConsoleColor.Cyan;
}else if ( string.IsNullOrWhiteSpace( lastmod1 ) ) // url in first sitemap only
{lm0col = ConsoleColor.Green;
urlcol = ConsoleColor.White;
}else if ( string.Compare( lastmod0, lastmod1 ) < 0 ) // url older in first sitemap
{lm0col = ConsoleColor.Red;
lm1col = ConsoleColor.Green;
urlcol = ConsoleColor.DarkYellow;
}else // url older in second sitemap
{lm0col = ConsoleColor.Green;
lm1col = ConsoleColor.Red;
urlcol = ConsoleColor.Yellow;
} }Console.ForegroundColor = lm0col;
Console.Write( "{0,10}\t", lastmod0 );
Console.ForegroundColor = lm1col;
Console.Write( "{0,10}\t", lastmod1 );
Console.ForegroundColor = urlcol;
Console.WriteLine( url );
lm0col = defcol;
lm1col = defcol;
urlcol = defcol;
} }if ( rc == 0 )
{Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine( "\nFiles are identical" );
} else {Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine( "\nFiles are different" );
}Console.ResetColor( );
if ( verbose )
{stopwatch.Stop( );
Console.WriteLine( "\nComparison took {0:0.000} seconds", stopwatch.Elapsed.TotalSeconds );
}return rc;
}static bool QuickTestXML( string file )
{ // Check if the file starts with "<?xml"StreamReader test = new StreamReader( file );
string firstline = test.ReadLine( );
test.Close( );
return ( firstline.StartsWith( "<?xml", StringComparison.OrdinalIgnoreCase ) );
} #region Error handlingpublic static int ShowHelp( params string[] errmsg )
{ #region Error Messageif ( errmsg.Length > 0 )
{System.Collections.Generic.List<string> errargs = new System.Collections.Generic.List<string>( errmsg );
errargs.RemoveAt( 0 );
Console.Error.WriteLine( );
Console.ForegroundColor = ConsoleColor.Red;
Console.Error.Write( "ERROR:\t" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( errmsg[0], errargs.ToArray( ) );
Console.ResetColor( );
} #endregion Error Message #region Help Text /* CompareSitemaps.exe, Version 1.00 Compare 2 XML sitemaps and display the differences on screen Usage: CompareSitemaps.exe sitemap1 sitemap2 [ /Q | /V ] Where: sitemap1, sitemap2 XML sitemap files to be compared /Q Quiet mode: no text, return code only /V Verbose mode: show all nodes (default: show differences only) Note: Return code 0 if files are identical, 1 if not, -1 on errors. Written by Rob van der Woude https://www.robvanderwoude.com */ #endregion Help Text #region Display helpConsole.Error.WriteLine( );
Console.Error.WriteLine( "CompareSitemaps.exe, Version {0}", progver );
Console.Error.WriteLine( "Compare 2 XML sitemaps and display the differences on screen" );
Console.Error.WriteLine( );
Console.Error.Write( "Usage: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.WriteLine( "CompareSitemaps.exe sitemap1 sitemap2 [ /V ]" );
Console.ResetColor( );
Console.Error.WriteLine( );
Console.Error.Write( "Where: " );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( "sitemap1, sitemap2" );
Console.ResetColor( );
Console.Error.WriteLine( " XML sitemap files to be compared" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " /Q Q" );
Console.ResetColor( );
Console.Error.WriteLine( "uiet mode: no text, return code only" );
Console.ForegroundColor = ConsoleColor.White;
Console.Error.Write( " /V V" );
Console.ResetColor( );
Console.Error.WriteLine( "erbose mode: show all nodes" );
Console.Error.WriteLine( " (default: show differences only)" );
Console.Error.WriteLine( );
Console.Error.WriteLine( "Note: Return code 0 if files are identical, 1 if not, -1 on errors." );
Console.Error.WriteLine( );
Console.Error.WriteLine( "Written by Rob van der Woude" );
Console.Error.WriteLine( "https://www.robvanderwoude.com" );
#endregion Display Helpreturn -1;
} #endregion Error handling }}page last modified: 2025-10-11; loaded in 0.0110 seconds