diff api/Factories/Xml/WarFoundryXmlFactory.cs @ 42:d0d44434b557

Fixes #45 - Fix XPath problems * Include namespace prefix and namespace manager in SelectNode calls, as per remark at http://msdn.microsoft.com/en-us/library/hcebdtae.aspx * Add SelectNodes method that always adds NamespaceManager * Fix XPath queries Also: * Add Army XSD to settings schema cache * Stop using deprecated Category constructor
author IBBoard <dev@ibboard.co.uk>
date Sun, 22 Mar 2009 16:37:43 +0000
parents 422ddd5fedd1
children d0812d7de39d
line wrap: on
line diff
--- a/api/Factories/Xml/WarFoundryXmlFactory.cs	Sat Mar 21 20:52:26 2009 +0000
+++ b/api/Factories/Xml/WarFoundryXmlFactory.cs	Sun Mar 22 16:37:43 2009 +0000
@@ -27,6 +27,7 @@
 	{
 		private static WarFoundryXmlFactory factory;
 		private XmlReaderSettings settings;
+		private XmlNamespaceManager nsManager;
 		private Dictionary<IWarFoundryObject, XmlDocument> extraData = new Dictionary<IWarFoundryObject, XmlDocument>();
 
 		public static AbstractNativeWarFoundryFactory GetFactory()
@@ -195,16 +196,15 @@
 			
 			system.SetAsLoading();
 			
-			XmlNode elem = GetExtraData(system);			
-			XmlNode catsElem = elem.FirstChild;
+			XmlNode elem = GetExtraData(system);
 			LoadCategoriesForSystem(system, elem);
-						
-			XmlElement statsElem = (XmlElement)catsElem.NextSibling;					
-			LoadSystemStatsFromElement(statsElem, system);
-			string defaultStatsID = statsElem.GetAttribute("defaultStats");
-								
+			XmlNodeList nodeList = SelectNodes(elem, "/system:system/system:categories");
+			XmlNode statsElem = nodeList.Item(0);
+			string defaultStatsID = ((XmlElement)statsElem).GetAttribute("defaultStats", "http://ibboard.co.uk/warfoundry/system");
+			LoadSystemStatsForSystem(system, elem);
+			system.StandardSystemStatsID = defaultStatsID;
 			LogNotifier.DebugFormat(GetType(), "Completed loading of GameSystem with ID {0}", system.Name);
-			system.StandardSystemStatsID = defaultStatsID;
+			LogNotifier.DebugFormat(GetType(), "GameSystem with ID {0} default stats: {1}", system.Name, system.StandardSystemStatsID);
 			system.SetAsFullyLoaded();
 		}
 		
@@ -212,7 +212,7 @@
 		{
 			WarFoundryObject tempObj;
 						
-			foreach (XmlElement cat in elem.SelectNodes("//"+WarFoundryXmlElementName.CATEGORY_ELEMENT.Value))
+			foreach (XmlElement cat in SelectNodes(elem, "/system:system/system:categories/cat:category"))
 			{
 				tempObj = CreateObjectFromElement(cat);
 				
@@ -320,6 +320,7 @@
 				AddSchemaToCache(cache, nsBase + "cats", path + "warfoundry-cats.xsd");
 				AddSchemaToCache(cache, nsBase + "race", path + "race.xsd");
 				AddSchemaToCache(cache, nsBase + "system", path + "system.xsd");
+				AddSchemaToCache(cache, nsBase + "army", path + "army.xsd");
 				settings.Schemas.Add(cache);
 			}
 			
@@ -346,6 +347,26 @@
 			}
 		}
 		
+		private XmlNamespaceManager GetNamespaceManager()
+		{
+			if (nsManager == null)
+			{
+				nsManager = new XmlNamespaceManager(new NameTable());
+				nsManager.AddNamespace("core", "http://ibboard.co.uk/warfoundry/core");
+				nsManager.AddNamespace("cat", "http://ibboard.co.uk/warfoundry/cats");
+				nsManager.AddNamespace("race", "http://ibboard.co.uk/warfoundry/race");
+				nsManager.AddNamespace("system", "http://ibboard.co.uk/warfoundry/system");
+				nsManager.AddNamespace("army", "http://ibboard.co.uk/warfoundry/army");
+			}
+			
+			return nsManager;
+		}
+		
+		private XmlNodeList SelectNodes(XmlNode element, string xpathQuery)
+		{
+			return element.SelectNodes(xpathQuery, GetNamespaceManager());
+		}
+		
 		private void ValidationEventMethod(object sender, ValidationEventArgs e)
 		{
 			throw new InvalidDataException("Problem validating against schema for WarFoundry data: " + e.Exception.Message, e.Exception);
@@ -373,18 +394,12 @@
 		{
 			string id = elem.GetAttribute("id");
 			string name = elem.GetAttribute("name");
-			int minPc, maxPc, minPts, maxPts, minChoices, maxChoices, baseValue, incValue, incAmount;
-			minPc = GetIntValueFromAttribute(elem, "minPercentage");
-			maxPc = GetIntValueFromAttribute(elem, "maxPercentage");
-			minPts = GetIntValueFromAttribute(elem, "minPoints");
-			maxPts = GetIntValueFromAttribute(elem, "maxPoints");
-			minChoices = GetIntValueFromAttribute(elem, "minChoices");
-			maxChoices = GetIntValueFromAttribute(elem, "maxChoices");
-			baseValue = GetIntValueFromAttribute(elem, "baseValue");
-			incValue = GetIntValueFromAttribute(elem, "incValue");
-			incAmount = GetIntValueFromAttribute(elem, "incAmount");
-						
-			return new Category(id, name, minPts, maxPts, minPc, maxPc, minChoices, maxChoices, baseValue, incValue, incAmount);
+			Category cat = new Category(id, name);
+			cat.MinimumPercentage = GetIntValueFromAttribute(elem, "minPercentage");
+			cat.MaximumPercentage = GetIntValueFromAttribute(elem, "maxPercentage");
+			cat.MinimumPoints = GetIntValueFromAttribute(elem, "minPoints");
+			cat.MaximumPoints = GetIntValueFromAttribute(elem, "maxPoints");
+			return cat;
 		}
 				
 		private int GetIntValueFromAttribute(XmlElement elem, string attributeName)
@@ -413,7 +428,7 @@
 			type.BaseUnitCost = GetIntValueFromAttribute(elem, "unitPoints");
 			string mainCatID = elem.GetAttribute("cat");
 			type.MainCategory = parentRace.GetCategory(mainCatID);						
-			XmlNodeList nodes = elem.SelectNodes("stats");
+			XmlNodeList nodes = SelectNodes(elem, "/race:race/race:units/race:unit/race:stats");
 			XmlNode node = nodes.Item(0);
 			type.UnitStats = ParseUnitStats((XmlElement)node, system);
 			//TODO: Add unit requirements
@@ -458,9 +473,9 @@
 			return stats;
 		}
 		
-		private void LoadSystemStatsFromElement(XmlElement elem, GameSystem system)
+		private void LoadSystemStatsForSystem(GameSystem system, XmlNode elem)
 		{
-			foreach (XmlElement stats in elem.ChildNodes)
+			foreach (XmlElement stats in SelectNodes(elem, "/system:system/system:sysStatsList/system:sysStats"))
 			{
 				SystemStats sysStats = CreateSystemStatsFromElement(stats);
 				system.AddSystemStats(sysStats);