diff --git a/HashingCmd/HashingCmd.csproj b/HashingCmd/HashingCmd.csproj
index ec77475b5e1d27daccf5e9a1ded6325072c8c14b..7ee07480a160366124db4c0ab30057e323729952 100644
--- a/HashingCmd/HashingCmd.csproj
+++ b/HashingCmd/HashingCmd.csproj
@@ -60,10 +60,18 @@
     <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\VectoCommon\VectoCommon\VectoCommon.csproj">
+      <Project>{79A066AD-69A9-4223-90F6-6ED5D2D084F4}</Project>
+      <Name>VectoCommon</Name>
+    </ProjectReference>
     <ProjectReference Include="..\VectoCommon\VectoHashing\VectoHashing.csproj">
       <Project>{B673E12F-D323-4C4C-8805-9915B2C72D3D}</Project>
       <Name>VectoHashing</Name>
     </ProjectReference>
+    <ProjectReference Include="..\VectoCore\VectoCore\VectoCore.csproj">
+      <Project>{CD36938A-ADD9-4C65-96DA-B397CDEEA90A}</Project>
+      <Name>VectoCore</Name>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
diff --git a/HashingCmd/Program.cs b/HashingCmd/Program.cs
index a9a57e21017aaad337588063400894bb6a02599e..d76254fff24bcdaf45b6b388eb9fce14bfcb6c2c 100644
--- a/HashingCmd/Program.cs
+++ b/HashingCmd/Program.cs
@@ -7,6 +7,12 @@ using System.Runtime.CompilerServices;
 using System.Text;
 using System.Threading.Tasks;
 using System.Xml;
+using System.Xml.Linq;
+using System.Xml.Schema;
+using System.Xml.XPath;
+using TUGraz.VectoCommon.Exceptions;
+using TUGraz.VectoCore.InputData.FileIO.XML.Declaration;
+using TUGraz.VectoCore.Utils;
 using TUGraz.VectoHashing;
 
 namespace HashingCmd
@@ -16,22 +22,26 @@ namespace HashingCmd
 		public delegate void HashingAction(string filename, VectoHash h);
 
 		private const string Usage = @"
-hashingcmd.exe -v <file.xml>
+hashingcmd.exe (-h | [-v] [[-s] -x] [-c] [-r]) <file.xml> <file2.xml> <file3.xml>
 
 ";
 
 		private const string Help = @"
 hashingcmd.exe
 
--h:    help
+-h:    print help
 -v:    verify hashed file
--s:    create hashed file file
+-s:    create hashed file
+-x:    validate generated XML against VECTO XML schema
 -c:    compute hash and write to stdout
 -r:    read hash from file and write to stdout
 ";
 
 		static Dictionary<string, HashingAction> actions = new Dictionary<string, HashingAction>();
 
+		static bool _validateXML = false;
+		private static bool xmlValid = true;
+
 		static int Main(string[] args)
 		{
 			try {
@@ -45,7 +55,16 @@ hashingcmd.exe
 				actions["-r"] = ReadHashAction;
 				actions["-s"] = CreateHashedFileAction;
 
-				var fileList = args.Except(actions.Keys);
+				if (args.Contains("-x")) {
+					_validateXML = true;
+				}
+
+				var fileList = args.Except(actions.Keys.Concat(new[] { "-x" })).ToArray();
+				if (fileList.Length == 0 || !args.Intersect(actions.Keys.ToArray()).Any()) {
+					ShowVersionInformation();
+					Console.Write(Usage);
+					return 0;
+				}
 				foreach (var file in fileList) {
 					WriteLine("processing " + Path.GetFileName(file));
 					if (!File.Exists(Path.GetFullPath(file))) {
@@ -60,6 +79,9 @@ hashingcmd.exe
 							} catch (Exception e) {
 								Console.ForegroundColor = ConsoleColor.Red;
 								Console.Error.WriteLine(e.Message);
+								if (e.InnerException != null) {
+									Console.Error.WriteLine(e.InnerException.Message);
+								}
 								Console.ResetColor();
 							}
 						}
@@ -101,6 +123,65 @@ hashingcmd.exe
 			result.WriteTo(writer);
 			writer.Flush();
 			writer.Close();
+
+			if (_validateXML) {
+				ValidateXML(destination);
+			}
+		}
+
+		private static void ValidateXML(string filename)
+		{
+			try {
+				var settings = new XmlReaderSettings {
+					ValidationType = ValidationType.Schema,
+					ValidationFlags = //XmlSchemaValidationFlags.ProcessInlineSchema |
+						//XmlSchemaValidationFlags.ProcessSchemaLocation |
+						XmlSchemaValidationFlags.ReportValidationWarnings
+				};
+				settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
+				settings.Schemas.Add(GetXMLSchema(""));
+
+				var vreader = XmlReader.Create(filename, settings);
+				var doc = new XmlDocument();
+				doc.Load(vreader);
+				doc.Validate(ValidationCallBack);
+				//while (vreader.Read()) {
+				//	Console.WriteLine(vreader.Value);
+				//}
+				if (xmlValid) {
+					WriteLine("Valid", ConsoleColor.Green);
+				}
+			} catch (Exception e) {
+				Console.ForegroundColor = ConsoleColor.Red;
+				Console.Error.WriteLine("Failed to validate hashed XML file!");
+				Console.Error.WriteLine(e.Message);
+				if (e.InnerException != null) {
+					Console.Error.WriteLine(e.InnerException.Message);
+				}
+				Console.ResetColor();
+			}
+		}
+
+		private static void ValidationCallBack(object sender, ValidationEventArgs args)
+		{
+			xmlValid = false;
+			if (args.Severity == XmlSeverityType.Error) {
+				throw new Exception(string.Format("Validation error: {0}" + Environment.NewLine +
+												"Line: {1}", args.Message, args.Exception.LineNumber));
+			} else {
+				Console.Error.WriteLine(string.Format("Validation warning: {0}" + Environment.NewLine +
+													"Line: {1}", args.Message, args.Exception.LineNumber));
+			}
+		}
+
+		private static XmlSchemaSet GetXMLSchema(string version)
+		{
+			var resource = RessourceHelper.LoadResourceAsStream(RessourceHelper.ResourceType.XMLSchema, "VectoComponent.xsd");
+			var xset = new XmlSchemaSet() { XmlResolver = new XmlResourceResolver() };
+			var reader = XmlReader.Create(resource, new XmlReaderSettings(), "schema://");
+			xset.Add(XmlSchema.Read(reader, null));
+			xset.Compile();
+			return xset;
 		}
 
 		private static void ReadHashAction(string filename, VectoHash h)
@@ -115,7 +196,7 @@ hashingcmd.exe
 				}
 				for (var i = 0; i < component.Count; i++) {
 					var readHash = h.ReadHash(component.Entry, i);
-					WriteLine("  " + component.Entry.XMLElementName() + "\t ... >" + readHash + "<");
+					WriteLine("  " + component.Entry.XMLElementName() + "\t ... " + readHash + "");
 				}
 			}
 		}
@@ -135,14 +216,14 @@ hashingcmd.exe
 					}
 					for (var i = 0; i < component.Count; i++) {
 						var computedHash = h.ComputeHash(component.Entry, i);
-						WriteLine("  " + component.Entry.XMLElementName() + "\t ... >" + computedHash + "<");
+						WriteLine("  " + component.Entry.XMLElementName() + "\t ... " + computedHash + "");
 					}
 				}
 				var jobHash = h.ComputeHash();
-				WriteLine("  job file\t ... >" + jobHash + "<");
+				WriteLine("  job file\t ... " + jobHash + "");
 			} else {
 				var hash = h.ComputeHash();
-				WriteLine("  computed hash:  >" + hash + "<");
+				WriteLine("  computed hash:  " + hash + "");
 			}
 		}
 
diff --git a/VectoCommon/VectoHashing/Resources/XSLT/SortInputData.xslt b/VectoCommon/VectoHashing/Resources/XSLT/SortInputData.xslt
index 1247151435447af97fb355b947040324b3e09e97..b77bd20244a953a7737e1333cc874e192fdb2d31 100644
--- a/VectoCommon/VectoHashing/Resources/XSLT/SortInputData.xslt
+++ b/VectoCommon/VectoHashing/Resources/XSLT/SortInputData.xslt
@@ -31,6 +31,7 @@
     </xsl:template>
 	<xsl:template match="*[local-name()='FuelConsumptionMap']">
 		<xsl:element name="{local-name()}">
+			<xsl:apply-templates select="@*"/>
 			<xsl:for-each select="*">
 				<xsl:sort data-type="number" select="@engineSpeed" order="ascending"/>
 				<xsl:sort data-type="number" select="@torque" order="ascending"/>
@@ -40,6 +41,7 @@
 	</xsl:template>
 	<xsl:template match="*[local-name()='FullLoadAndDragCurve']">
 		<xsl:element name="{local-name()}">
+			<xsl:apply-templates select="@*"/>
 			<xsl:for-each select="*">
 				<xsl:sort data-type="number" select="@engineSpeed" order="ascending"/>
 				<xsl:apply-templates select="."/>
@@ -48,6 +50,7 @@
 	</xsl:template>
 	<xsl:template match="*[local-name()='TorqueLossMap']">
 		<xsl:element name="{local-name()}">
+			<xsl:apply-templates select="@*"/>
 			<xsl:for-each select="*">
 				<xsl:sort data-type="number" select="@inputSpeed" order="ascending"/>
 				<xsl:sort data-type="number" select="@inputTorque" order="ascending"/>
@@ -57,6 +60,7 @@
 	</xsl:template>
 	<xsl:template match="*[local-name()='RetarderLossMap']">
 		<xsl:element name="{local-name()}">
+			<xsl:apply-templates select="@*"/>
 			<xsl:for-each select="*">
 				<xsl:sort data-type="number" select="@retarderSpeed" order="ascending"/>
 				<xsl:apply-templates select="."/>
@@ -65,6 +69,7 @@
 	</xsl:template>
 	<xsl:template match="*[local-name()='TorqueLimits']">
 		<xsl:element name="{local-name()}">
+			<xsl:apply-templates select="@*"/>
 			<xsl:for-each select="*">
 				<xsl:sort data-type="number" select="@gear" order="ascending"/>
 				<xsl:apply-templates select="."/>
@@ -73,6 +78,7 @@
 	</xsl:template>
 	<xsl:template match="*[local-name()='Gears']">
 		<xsl:element name="{local-name()}">
+			<xsl:apply-templates select="@*"/>
 			<xsl:for-each select="*">
 				<xsl:sort data-type="number" select="@number" order="ascending"/>
 				<xsl:apply-templates select="."/>
@@ -81,6 +87,7 @@
 	</xsl:template>
 	<xsl:template match="*[local-name()='Characteristics']">
 		<xsl:element name="{local-name()}">
+			<xsl:apply-templates select="@*"/>
 			<xsl:for-each select="*">
 				<xsl:sort data-type="number" select="@speedRatio" order="ascending"/>
 				<xsl:apply-templates select="."/>
@@ -88,6 +95,7 @@
 		</xsl:element>
 	</xsl:template>
 	<xsl:template match="*[local-name()='Axles']">
+		<xsl:apply-templates select="@*"/>
 		<xsl:element name="{local-name()}">
 			<xsl:for-each select="*">
 				<xsl:sort data-type="number" select="@axleNumber" order="ascending"/>
diff --git a/VectoCommon/VectoHashing/VectoHash.cs b/VectoCommon/VectoHashing/VectoHash.cs
index 4ba0be427e5e8aea5c1bc96f2a0c62e591b8b19a..ef31b0c15028f9962dc7e4f222b932a08832aebd 100644
--- a/VectoCommon/VectoHashing/VectoHash.cs
+++ b/VectoCommon/VectoHashing/VectoHash.cs
@@ -19,14 +19,22 @@ namespace TUGraz.VectoHashing
 		public static VectoHash Load(string filename)
 		{
 			var doc = new XmlDocument();
-			doc.Load(new XmlTextReader(filename));
+			try {
+				doc.Load(new XmlTextReader(filename));
+			} catch (Exception e) {
+				throw new Exception("failed to read XML document", e);
+			}
 			return new VectoHash(doc);
 		}
 
 		public static VectoHash Load(Stream stream)
 		{
 			var doc = new XmlDocument();
-			doc.Load(new XmlTextReader(stream));
+			try {
+				doc.Load(new XmlTextReader(stream));
+			} catch (Exception e) {
+				throw new Exception("failed to read XML document", e);
+			}
 			return new VectoHash(doc);
 		}
 
@@ -77,12 +85,15 @@ namespace TUGraz.VectoHashing
 			if (components.Count > 1) {
 				throw new Exception("input must not contain multiple components!");
 			}
-			var query = string.Format("//*[local-name()='{0}']/*[local-name()='Data']", components[0]);
+			if (components.Count == 0) {
+				throw new Exception("input does not contain a known component!");
+			}
+			var query = string.Format("//*[local-name()='{0}']/*[local-name()='Data']", components[0].XMLElementName());
 			var node = Document.SelectSingleNode(query);
 			if (node == null) {
-				throw new Exception(string.Format("'Data' element for component '{0}' not found!", components[0]));
+				throw new Exception(string.Format("'Data' element for component '{0}' not found!", components[0].XMLElementName()));
 			}
-			query = string.Format("//*[local-name()='{0}']/*[local-name()='Signature']", components[0]);
+			query = string.Format("//*[local-name()='{0}']/*[local-name()='Signature']", components[0].XMLElementName());
 			var sigNodes = Document.SelectNodes(query);
 			if (sigNodes != null && sigNodes.Count > 0) {
 				throw new Exception("input data already contains a signature element");
@@ -160,8 +171,15 @@ namespace TUGraz.VectoHashing
 
 		private static string GetHashValue(XmlDocument hashed, string elementToHash)
 		{
-			var node = hashed.SelectSingleNode("//*[@URI='#" + elementToHash + "']/*[local-name() = 'DigestValue']");
-			return node == null ? null : node.InnerText;
+			//var node = hashed.SelectSingleNode("//*[@URI='#" + elementToHash + "']/*[local-name() = 'DigestValue']");
+			var nodes = hashed.SelectNodes("//*[@URI='#" + elementToHash + "']/*[local-name() = 'DigestValue']");
+			if (nodes == null || nodes.Count == 0) {
+				return null;
+			}
+			if (nodes.Count > 1) {
+				throw new Exception("Multiple DigestValue elements found!");
+			}
+			return nodes[0].InnerText;
 		}
 	}
 }
\ No newline at end of file