Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for comparesitemaps.cs

(view source code of comparesitemaps.cs as plain text)

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Xml;
  6.  
  7.  
  8. namespace RobvanderWoude
  9. {
  10. 	internal class CompareSitemaps
  11. 	{
  12. 		static readonly string progver = "1.00";
  13.  
  14.  
  15. 		static int Main( string[] args )
  16. 		{
  17. 			int rc = 0;
  18. 			bool quiet = false;
  19. 			bool verbose = false;
  20. 			Stopwatch stopwatch = new Stopwatch( );
  21.  
  22.  
  23. 			#region Command Line Parsing
  24.  
  25. 			if ( args.Length < 2 || args.Length > 3 )
  26. 			{
  27. 				return ShowHelp( );
  28. 			}
  29.  
  30. 			if ( args.Length == 3 )
  31. 			{
  32. 				if ( args[2].ToUpper( ) == "/V" )
  33. 				{
  34. 					verbose = true;
  35. 				}
  36. 				else if ( args[2].ToUpper( ) == "/Q" )
  37. 				{
  38. 					quiet = true;
  39. 				}
  40. 				else
  41. 				{
  42. 					return ShowHelp( );
  43. 				}
  44. 			}
  45.  
  46. 			if ( !File.Exists( args[0] ) )
  47. 			{
  48. 				return ShowHelp( "File \"{0}\" not found", args[0] );
  49. 			}
  50.  
  51. 			if ( !File.Exists( args[1] ) )
  52. 			{
  53. 				return ShowHelp( "File \"{0}\" not found", args[1] );
  54. 			}
  55.  
  56. 			if ( !QuickTestXML( args[0] ) )
  57. 			{
  58. 				return ShowHelp( "File \"{0}\" is not an XML file", args[0] );
  59. 			}
  60.  
  61. 			if ( !QuickTestXML( args[1] ) )
  62. 			{
  63. 				return ShowHelp( "File \"{0}\" is not an XML file", args[1] );
  64. 			}
  65.  
  66. 			#endregion Command Line Parsing
  67.  
  68.  
  69. 			if ( verbose )
  70. 			{
  71. 				stopwatch.Start( );
  72. 			}
  73.  
  74.  
  75. 			#region Open XML
  76.  
  77. 			XmlReader xml0r = XmlReader.Create( args[0] );
  78. 			XmlDocument xml0d = new XmlDocument( );
  79. 			xml0d.Load( xml0r );
  80. 			XmlReader xml1r= XmlReader.Create( args[1] );
  81. 			XmlDocument xml1d = new XmlDocument( );
  82. 			xml1d.Load( xml1r );
  83.  
  84. 			int nodecount0 = xml0d.DocumentElement.ChildNodes.Count;
  85. 			int nodecount1 = xml1d.DocumentElement.ChildNodes.Count;
  86. 			if ( nodecount0 != nodecount1 )
  87. 			{
  88. 				rc = 1;
  89. 				if ( quiet )
  90. 				{
  91. 					return 1;
  92. 				}
  93. 			}
  94.  
  95. 			#endregion Open XML
  96.  
  97.  
  98. 			if ( verbose )
  99. 			{
  100. 				Single filesize0 = new FileInfo( args[0] ).Length / 1048576;
  101. 				Single filesize1 = new FileInfo( args[1] ).Length / 1048576; 
  102.  
  103. 				Console.WriteLine( "Files to compare:" );
  104. 				Console.WriteLine( "=================" );
  105. 				Console.WriteLine( "{0,5:0.00} MB    {1,7} nodes    {2}", filesize0, nodecount0, Path.GetFullPath( args[0] ) );
  106. 				Console.WriteLine( "{0,5:0.00} MB    {1,7} nodes    {2}", filesize1, nodecount1, Path.GetFullPath( args[1] ) );
  107. 				Console.WriteLine( );
  108. 			}
  109.  
  110.  
  111. 			#region Read XML
  112.  
  113. 			SortedList<string, string> urls = new SortedList<string, string>( );
  114. 			SortedList<string, string> urls0 = new SortedList<string, string>( );
  115. 			SortedList<string, string> urls1 = new SortedList<string, string>( );
  116. 			for ( int i = 0; i < nodecount0; i++ )
  117. 			{
  118. 				string url = xml0d.DocumentElement.ChildNodes[i].ChildNodes[0].InnerText;
  119. 				string lastmod = xml0d.DocumentElement.ChildNodes[i].ChildNodes[1].InnerText;
  120. 				urls[url] = url;
  121. 				urls0[url] = lastmod;
  122. 			}
  123. 			for ( int i = 0; i < nodecount1; i++ )
  124. 			{
  125. 				string url = xml1d.DocumentElement.ChildNodes[i].ChildNodes[0].InnerText;
  126. 				string lastmod = xml1d.DocumentElement.ChildNodes[i].ChildNodes[1].InnerText;
  127. 				urls[url] = url;
  128. 				urls1[url] = lastmod;
  129. 			}
  130.  
  131. 			xml0r.Close( );
  132. 			xml1r.Close( );
  133.  
  134. 			#endregion Read XML
  135.  
  136.  
  137. 			Console.ForegroundColor = ConsoleColor.Black;
  138. 			Console.BackgroundColor = ConsoleColor.White;
  139. 			int width = Console.WindowWidth;
  140. 			Console.WriteLine( new String( ' ', width - 1 ) );
  141. 			Console.WriteLine( "Sitemap0:     Sitemap1:     URL:{0}", new string( ' ', width - 33 ) );
  142. 			Console.WriteLine( new String( ' ', width - 1 ) );
  143. 			Console.ResetColor( );
  144. 			Console.WriteLine( );
  145.  
  146. 			ConsoleColor defcol = Console.ForegroundColor;
  147. 			ConsoleColor lm0col = defcol;
  148. 			ConsoleColor lm1col = defcol;
  149. 			ConsoleColor urlcol = defcol;
  150.  
  151. 			for ( int i = 0; i < urls.Keys.Count; i++ )
  152. 			{
  153. 				string url = urls.Keys[i];
  154. 				string lastmod0 = string.Empty;
  155. 				string lastmod1 = string.Empty;
  156. 				if ( urls0.ContainsKey( url ) )
  157. 				{
  158. 					lastmod0 = urls0[url];
  159. 				}
  160. 				if ( urls1.ContainsKey( url ) )
  161. 				{
  162. 					lastmod1 = urls1[url];
  163. 				}
  164. 				if ( verbose || lastmod0 != lastmod1 )
  165. 				{
  166. 					if ( lastmod0 != lastmod1 )
  167. 					{
  168. 						rc = 1;
  169. 						if ( quiet )
  170. 						{
  171. 							return 1;
  172. 						}
  173. 						if ( string.IsNullOrWhiteSpace( lastmod0 ) ) // url in second sitemap only
  174. 						{
  175. 							lm1col = ConsoleColor.Red;
  176. 							urlcol = ConsoleColor.Cyan;
  177. 						}
  178. 						else if ( string.IsNullOrWhiteSpace( lastmod1 ) ) // url in first sitemap only
  179. 						{
  180. 							lm0col = ConsoleColor.Green;
  181. 							urlcol = ConsoleColor.White;
  182. 						}
  183. 						else if ( string.Compare( lastmod0, lastmod1 ) < 0 ) // url older in first sitemap
  184. 						{
  185. 							lm0col = ConsoleColor.Red;
  186. 							lm1col = ConsoleColor.Green;
  187. 							urlcol = ConsoleColor.DarkYellow;
  188. 						}
  189. 						else // url older in second sitemap
  190. 						{
  191. 							lm0col = ConsoleColor.Green;
  192. 							lm1col = ConsoleColor.Red;
  193. 							urlcol = ConsoleColor.Yellow;
  194. 						}
  195. 					}
  196. 					Console.ForegroundColor = lm0col;
  197. 					Console.Write( "{0,10}\t", lastmod0 );
  198. 					Console.ForegroundColor = lm1col;
  199. 					Console.Write( "{0,10}\t", lastmod1 );
  200. 					Console.ForegroundColor = urlcol;
  201. 					Console.WriteLine( url );
  202. 					lm0col = defcol;
  203. 					lm1col = defcol;
  204. 					urlcol = defcol;
  205. 				}
  206. 			}
  207.  
  208. 			if ( rc == 0 )
  209. 			{
  210. 				Console.ForegroundColor = ConsoleColor.Green;
  211. 				Console.WriteLine( "\nFiles are identical" );
  212. 			}
  213. 			else
  214. 			{
  215. 				Console.ForegroundColor = ConsoleColor.Red;
  216. 				Console.WriteLine( "\nFiles are different" );
  217. 			}
  218. 			Console.ResetColor( );
  219.  
  220. 			if ( verbose )
  221. 			{
  222. 				stopwatch.Stop( );
  223. 				Console.WriteLine( "\nComparison took {0:0.000} seconds", stopwatch.Elapsed.TotalSeconds );
  224. 			}
  225.  
  226. 			return rc;
  227. 		}
  228.  
  229.  
  230. 		static bool QuickTestXML( string file )
  231. 		{
  232. 			// Check if the file starts with "<?xml"
  233. 			StreamReader test = new StreamReader( file );
  234. 			string firstline = test.ReadLine( );
  235. 			test.Close( );
  236. 			return ( firstline.StartsWith( "<?xml", StringComparison.OrdinalIgnoreCase ) );
  237. 		}
  238.  
  239.  
  240. 		#region Error handling
  241.  
  242. 		public static int ShowHelp( params string[] errmsg )
  243. 		{
  244. 			#region Error Message
  245.  
  246. 			if ( errmsg.Length > 0 )
  247. 			{
  248. 				System.Collections.Generic.List<string> errargs = new System.Collections.Generic.List<string>( errmsg );
  249. 				errargs.RemoveAt( 0 );
  250. 				Console.Error.WriteLine( );
  251. 				Console.ForegroundColor = ConsoleColor.Red;
  252. 				Console.Error.Write( "ERROR:\t" );
  253. 				Console.ForegroundColor = ConsoleColor.White;
  254. 				Console.Error.WriteLine( errmsg[0], errargs.ToArray( ) );
  255. 				Console.ResetColor( );
  256. 			}
  257.  
  258. 			#endregion Error Message
  259.  
  260.  
  261. 			#region Help Text
  262.  
  263. 			/*
  264. 			CompareSitemaps.exe,  Version 1.00
  265. 			Compare 2 XML sitemaps and display the differences on screen
  266.  
  267. 			Usage:   CompareSitemaps.exe  sitemap1  sitemap2  [ /Q | /V ]
  268.  
  269. 			Where:   sitemap1, sitemap2   XML sitemap files to be compared
  270. 			         /Q                   Quiet mode: no text, return code only
  271. 			         /V                   Verbose mode: show all nodes
  272. 			                              (default: show differences only)
  273.  
  274. 			Note:    Return code 0 if files are identical, 1 if not, -1 on errors.
  275.  
  276. 			Written by Rob van der Woude
  277. 			https://www.robvanderwoude.com
  278. 			*/
  279.  
  280. 			#endregion Help Text
  281.  
  282.  
  283. 			#region Display help
  284.  
  285. 			Console.Error.WriteLine( );
  286.  
  287. 			Console.Error.WriteLine( "CompareSitemaps.exe,  Version {0}", progver );
  288.  
  289. 			Console.Error.WriteLine( "Compare 2 XML sitemaps and display the differences on screen" );
  290.  
  291. 			Console.Error.WriteLine( );
  292.  
  293. 			Console.Error.Write( "Usage:   " );
  294. 			Console.ForegroundColor = ConsoleColor.White;
  295. 			Console.Error.WriteLine( "CompareSitemaps.exe  sitemap1  sitemap2  [ /V ]" );
  296. 			Console.ResetColor( );
  297.  
  298. 			Console.Error.WriteLine( );
  299.  
  300. 			Console.Error.Write( "Where:   " );
  301. 			Console.ForegroundColor = ConsoleColor.White;
  302. 			Console.Error.Write( "sitemap1, sitemap2" );
  303. 			Console.ResetColor( );
  304. 			Console.Error.WriteLine( "   XML sitemap files to be compared" );
  305.  
  306. 			Console.ForegroundColor = ConsoleColor.White;
  307. 			Console.Error.Write( "         /Q                   Q" );
  308. 			Console.ResetColor( );
  309. 			Console.Error.WriteLine( "uiet mode: no text, return code only" );
  310.  
  311. 			Console.ForegroundColor = ConsoleColor.White;
  312. 			Console.Error.Write( "         /V                   V" );
  313. 			Console.ResetColor( );
  314. 			Console.Error.WriteLine( "erbose mode: show all nodes" );
  315.  
  316. 			Console.Error.WriteLine( "                              (default: show differences only)" );
  317.  
  318. 			Console.Error.WriteLine( );
  319.  
  320. 			Console.Error.WriteLine( "Note:    Return code 0 if files are identical, 1 if not, -1 on errors." );
  321.  
  322. 			Console.Error.WriteLine( );
  323.  
  324. 			Console.Error.WriteLine( "Written by Rob van der Woude" );
  325.  
  326. 			Console.Error.WriteLine( "https://www.robvanderwoude.com" );
  327.  
  328. 			#endregion Display Help
  329.  
  330.  
  331. 			return -1;
  332. 		}
  333.  
  334. 		#endregion Error handling
  335. 	}
  336. }

page last modified: 2022-10-20