comparison 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
comparison
equal deleted inserted replaced
41:422ddd5fedd1 42:d0d44434b557
25 /// </summary> 25 /// </summary>
26 public class WarFoundryXmlFactory : AbstractNativeWarFoundryFactory 26 public class WarFoundryXmlFactory : AbstractNativeWarFoundryFactory
27 { 27 {
28 private static WarFoundryXmlFactory factory; 28 private static WarFoundryXmlFactory factory;
29 private XmlReaderSettings settings; 29 private XmlReaderSettings settings;
30 private XmlNamespaceManager nsManager;
30 private Dictionary<IWarFoundryObject, XmlDocument> extraData = new Dictionary<IWarFoundryObject, XmlDocument>(); 31 private Dictionary<IWarFoundryObject, XmlDocument> extraData = new Dictionary<IWarFoundryObject, XmlDocument>();
31 32
32 public static AbstractNativeWarFoundryFactory GetFactory() 33 public static AbstractNativeWarFoundryFactory GetFactory()
33 { 34 {
34 if (factory == null) 35 if (factory == null)
193 return; 194 return;
194 } 195 }
195 196
196 system.SetAsLoading(); 197 system.SetAsLoading();
197 198
198 XmlNode elem = GetExtraData(system); 199 XmlNode elem = GetExtraData(system);
199 XmlNode catsElem = elem.FirstChild;
200 LoadCategoriesForSystem(system, elem); 200 LoadCategoriesForSystem(system, elem);
201 201 XmlNodeList nodeList = SelectNodes(elem, "/system:system/system:categories");
202 XmlElement statsElem = (XmlElement)catsElem.NextSibling; 202 XmlNode statsElem = nodeList.Item(0);
203 LoadSystemStatsFromElement(statsElem, system); 203 string defaultStatsID = ((XmlElement)statsElem).GetAttribute("defaultStats", "http://ibboard.co.uk/warfoundry/system");
204 string defaultStatsID = statsElem.GetAttribute("defaultStats"); 204 LoadSystemStatsForSystem(system, elem);
205 205 system.StandardSystemStatsID = defaultStatsID;
206 LogNotifier.DebugFormat(GetType(), "Completed loading of GameSystem with ID {0}", system.Name); 206 LogNotifier.DebugFormat(GetType(), "Completed loading of GameSystem with ID {0}", system.Name);
207 system.StandardSystemStatsID = defaultStatsID; 207 LogNotifier.DebugFormat(GetType(), "GameSystem with ID {0} default stats: {1}", system.Name, system.StandardSystemStatsID);
208 system.SetAsFullyLoaded(); 208 system.SetAsFullyLoaded();
209 } 209 }
210 210
211 private void LoadCategoriesForSystem(GameSystem system, XmlNode elem) 211 private void LoadCategoriesForSystem(GameSystem system, XmlNode elem)
212 { 212 {
213 WarFoundryObject tempObj; 213 WarFoundryObject tempObj;
214 214
215 foreach (XmlElement cat in elem.SelectNodes("//"+WarFoundryXmlElementName.CATEGORY_ELEMENT.Value)) 215 foreach (XmlElement cat in SelectNodes(elem, "/system:system/system:categories/cat:category"))
216 { 216 {
217 tempObj = CreateObjectFromElement(cat); 217 tempObj = CreateObjectFromElement(cat);
218 218
219 if (tempObj is Category) 219 if (tempObj is Category)
220 { 220 {
318 string nsBase = "http://ibboard.co.uk/warfoundry/"; 318 string nsBase = "http://ibboard.co.uk/warfoundry/";
319 AddSchemaToCache(cache, nsBase + "core", path + "warfoundry-core.xsd"); 319 AddSchemaToCache(cache, nsBase + "core", path + "warfoundry-core.xsd");
320 AddSchemaToCache(cache, nsBase + "cats", path + "warfoundry-cats.xsd"); 320 AddSchemaToCache(cache, nsBase + "cats", path + "warfoundry-cats.xsd");
321 AddSchemaToCache(cache, nsBase + "race", path + "race.xsd"); 321 AddSchemaToCache(cache, nsBase + "race", path + "race.xsd");
322 AddSchemaToCache(cache, nsBase + "system", path + "system.xsd"); 322 AddSchemaToCache(cache, nsBase + "system", path + "system.xsd");
323 AddSchemaToCache(cache, nsBase + "army", path + "army.xsd");
323 settings.Schemas.Add(cache); 324 settings.Schemas.Add(cache);
324 } 325 }
325 326
326 return settings; 327 return settings;
327 } 328 }
342 } 343 }
343 catch (XmlException ex) 344 catch (XmlException ex)
344 { 345 {
345 LogNotifier.Warn(GetType(), "Problem reading data for schema: " + ex.Message, ex); 346 LogNotifier.Warn(GetType(), "Problem reading data for schema: " + ex.Message, ex);
346 } 347 }
348 }
349
350 private XmlNamespaceManager GetNamespaceManager()
351 {
352 if (nsManager == null)
353 {
354 nsManager = new XmlNamespaceManager(new NameTable());
355 nsManager.AddNamespace("core", "http://ibboard.co.uk/warfoundry/core");
356 nsManager.AddNamespace("cat", "http://ibboard.co.uk/warfoundry/cats");
357 nsManager.AddNamespace("race", "http://ibboard.co.uk/warfoundry/race");
358 nsManager.AddNamespace("system", "http://ibboard.co.uk/warfoundry/system");
359 nsManager.AddNamespace("army", "http://ibboard.co.uk/warfoundry/army");
360 }
361
362 return nsManager;
363 }
364
365 private XmlNodeList SelectNodes(XmlNode element, string xpathQuery)
366 {
367 return element.SelectNodes(xpathQuery, GetNamespaceManager());
347 } 368 }
348 369
349 private void ValidationEventMethod(object sender, ValidationEventArgs e) 370 private void ValidationEventMethod(object sender, ValidationEventArgs e)
350 { 371 {
351 throw new InvalidDataException("Problem validating against schema for WarFoundry data: " + e.Exception.Message, e.Exception); 372 throw new InvalidDataException("Problem validating against schema for WarFoundry data: " + e.Exception.Message, e.Exception);
371 392
372 private Category CreateCategoryFromElement(XmlElement elem) 393 private Category CreateCategoryFromElement(XmlElement elem)
373 { 394 {
374 string id = elem.GetAttribute("id"); 395 string id = elem.GetAttribute("id");
375 string name = elem.GetAttribute("name"); 396 string name = elem.GetAttribute("name");
376 int minPc, maxPc, minPts, maxPts, minChoices, maxChoices, baseValue, incValue, incAmount; 397 Category cat = new Category(id, name);
377 minPc = GetIntValueFromAttribute(elem, "minPercentage"); 398 cat.MinimumPercentage = GetIntValueFromAttribute(elem, "minPercentage");
378 maxPc = GetIntValueFromAttribute(elem, "maxPercentage"); 399 cat.MaximumPercentage = GetIntValueFromAttribute(elem, "maxPercentage");
379 minPts = GetIntValueFromAttribute(elem, "minPoints"); 400 cat.MinimumPoints = GetIntValueFromAttribute(elem, "minPoints");
380 maxPts = GetIntValueFromAttribute(elem, "maxPoints"); 401 cat.MaximumPoints = GetIntValueFromAttribute(elem, "maxPoints");
381 minChoices = GetIntValueFromAttribute(elem, "minChoices"); 402 return cat;
382 maxChoices = GetIntValueFromAttribute(elem, "maxChoices");
383 baseValue = GetIntValueFromAttribute(elem, "baseValue");
384 incValue = GetIntValueFromAttribute(elem, "incValue");
385 incAmount = GetIntValueFromAttribute(elem, "incAmount");
386
387 return new Category(id, name, minPts, maxPts, minPc, maxPc, minChoices, maxChoices, baseValue, incValue, incAmount);
388 } 403 }
389 404
390 private int GetIntValueFromAttribute(XmlElement elem, string attributeName) 405 private int GetIntValueFromAttribute(XmlElement elem, string attributeName)
391 { 406 {
392 try 407 try
411 //TODO: Add base size 426 //TODO: Add base size
412 type.CostPerTrooper = GetIntValueFromAttribute(elem, "points"); 427 type.CostPerTrooper = GetIntValueFromAttribute(elem, "points");
413 type.BaseUnitCost = GetIntValueFromAttribute(elem, "unitPoints"); 428 type.BaseUnitCost = GetIntValueFromAttribute(elem, "unitPoints");
414 string mainCatID = elem.GetAttribute("cat"); 429 string mainCatID = elem.GetAttribute("cat");
415 type.MainCategory = parentRace.GetCategory(mainCatID); 430 type.MainCategory = parentRace.GetCategory(mainCatID);
416 XmlNodeList nodes = elem.SelectNodes("stats"); 431 XmlNodeList nodes = SelectNodes(elem, "/race:race/race:units/race:unit/race:stats");
417 XmlNode node = nodes.Item(0); 432 XmlNode node = nodes.Item(0);
418 type.UnitStats = ParseUnitStats((XmlElement)node, system); 433 type.UnitStats = ParseUnitStats((XmlElement)node, system);
419 //TODO: Add unit requirements 434 //TODO: Add unit requirements
420 LogNotifier.Debug(GetType(), "Loaded "+type.Name); 435 LogNotifier.Debug(GetType(), "Loaded "+type.Name);
421 return type; 436 return type;
456 stats.SetStats(statsList); 471 stats.SetStats(statsList);
457 472
458 return stats; 473 return stats;
459 } 474 }
460 475
461 private void LoadSystemStatsFromElement(XmlElement elem, GameSystem system) 476 private void LoadSystemStatsForSystem(GameSystem system, XmlNode elem)
462 { 477 {
463 foreach (XmlElement stats in elem.ChildNodes) 478 foreach (XmlElement stats in SelectNodes(elem, "/system:system/system:sysStatsList/system:sysStats"))
464 { 479 {
465 SystemStats sysStats = CreateSystemStatsFromElement(stats); 480 SystemStats sysStats = CreateSystemStatsFromElement(stats);
466 system.AddSystemStats(sysStats); 481 system.AddSystemStats(sysStats);
467 } 482 }
468 } 483 }