diff api/Factories/Xml/WarFoundryXmlFactory.cs @ 23:f9846f896df3

Re #32 - Migrate WarFoundry files to using Schemas * Add missing spaces to Cats and Core XSD * Fix some incorrect namespaces in Race XSD * Copy schemas to output dir on build * Make WarFoundryXmlFactory validate against Schemas * Make WarFoundryLoader handle failed file loads slightly differently so that we can log out as a warning * Correctly structure "simpleContent" sections of Race XSD Still to do: * Work out why Race XSD doesn't like core:nonNegativeDecimal but appears to be fine with core:percentage * Migrate test files to define namespaces and make sure they match the structure
author IBBoard <dev@ibboard.co.uk>
date Thu, 12 Mar 2009 21:35:17 +0000
parents a99d3b8466ba
children 457c9357dd64
line wrap: on
line diff
--- a/api/Factories/Xml/WarFoundryXmlFactory.cs	Mon Mar 09 20:45:45 2009 +0000
+++ b/api/Factories/Xml/WarFoundryXmlFactory.cs	Thu Mar 12 21:35:17 2009 +0000
@@ -25,6 +25,7 @@
 	public class WarFoundryXmlFactory : AbstractNativeWarFoundryFactory
 	{
 		private static WarFoundryXmlFactory factory;
+		private XmlReaderSettings settings;
 		private Dictionary<IWarFoundryObject, XmlDocument> extraData = new Dictionary<IWarFoundryObject, XmlDocument>();
 		private XmlResolver xmlResolver;
 
@@ -266,12 +267,7 @@
 		protected XmlDocument CreateXmlDocumentFromStream(Stream stream)
 		{
 			XmlDocument doc = new XmlDocument();
-			XmlReaderSettings settings = new XmlReaderSettings();
-			settings.XmlResolver = xmlResolver;
-			settings.ValidationType = ValidationType.DTD;
-			settings.ProhibitDtd = false;
-			settings.ValidationEventHandler+= new ValidationEventHandler(ValidationEventMethod);
-			XmlReader reader = XmlReader.Create(stream, settings);
+			XmlReader reader = XmlReader.Create(stream, GetReaderSettings());
 			
 			try
 			{
@@ -289,6 +285,51 @@
 			}
 
 			return doc;
+		}
+		
+				/// <summary>
+		/// Lazy-getter for XML reader settings. May throw a <see cref="InvalidDataException"/> if there is a problem with the translation schema.
+		/// </summary>
+		/// <returns>
+		/// A <see cref="XmlReaderSettings"/> with the default values for validating the translation document against the translation schema
+		/// </returns>
+		private XmlReaderSettings GetReaderSettings()
+		{
+			if (settings == null)
+			{
+				try
+				{
+					settings = new XmlReaderSettings();
+					settings.ValidationType = ValidationType.Schema;
+					settings.ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings;
+					settings.ValidationEventHandler+= new ValidationEventHandler(ValidationEventMethod);
+					XmlSchemaSet cache = new XmlSchemaSet();
+					cache.Add("http://ibboard.co.uk/warfoundry/core", IBBoard.Constants.ExecutablePath + "/dtds/warfoundry-core.xsd");
+					cache.Add("http://ibboard.co.uk/warfoundry/cats", IBBoard.Constants.ExecutablePath + "/dtds/warfoundry-cats.xsd");
+					cache.Add("http://ibboard.co.uk/warfoundry/race", IBBoard.Constants.ExecutablePath + "/dtds/race.xsd");
+					cache.Add("http://ibboard.co.uk/warfoundry/system", IBBoard.Constants.ExecutablePath + "/dtds/system.xsd");
+					settings.Schemas.Add(cache);
+				}
+				catch (DirectoryNotFoundException ex)
+				{
+					throw new InvalidDataException("Problem validating schema for WarFoundry data: " + ex.Message, ex);
+				}
+				catch (XmlSchemaException ex)
+				{
+					throw new InvalidDataException("Problem validating schema for WarFoundry data: " + ex.Message, ex);
+				}
+				catch (XmlException ex)
+				{
+					throw new InvalidDataException("Problem reading data for schema: " + ex.Message, ex);
+				}
+			}
+			
+			return settings;
+		}
+		
+		private void ValidationEventMethod(object sender, ValidationEventArgs e)
+		{
+			throw new InvalidDataException("Problem validating against schema for WarFoundry data: " + e.Exception.Message, e.Exception);
 		}
 
 		protected XmlDocument CreateXmlDocumentFromString(string xmlString)
@@ -512,11 +553,5 @@
 			
 			return new EquipmentItem(id, name, cost, min, max, armourType, race);
 		}
-		
-		private void ValidationEventMethod(object sender, ValidationEventArgs e)
-		{
-			//TODO: Fire a validation failure event
-    		LogNotifier.WarnFormat(GetType(), "Validation Error: {0}", e.Message);
-		}
 	}
 }
\ No newline at end of file