Mercurial > repos > IBBoard.WarFoundry.API
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 } |