Mercurial > repos > IBDev-IBBoard.WarFoundry.API
changeset 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 | 28e99aa0053f |
children | 72312a7ac08a |
files | IBBoard.WarFoundry.API.csproj api/Factories/Xml/WarFoundryXmlFactory.cs api/WarFoundryLoader.cs dtds/race.xsd dtds/warfoundry-cats.xsd dtds/warfoundry-core.xsd |
diffstat | 6 files changed, 97 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/IBBoard.WarFoundry.API.csproj Mon Mar 09 20:45:45 2009 +0000 +++ b/IBBoard.WarFoundry.API.csproj Thu Mar 12 21:35:17 2009 +0000 @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> @@ -44,6 +44,18 @@ <None Include="dtds\army.dtd" /> <None Include="dtds\race.dtd" /> <None Include="dtds\system.dtd" /> + <None Include="dtds\system.xsd"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="dtds\race.xsd"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="dtds\warfoundry-core.xsd"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="dtds\warfoundry-cats.xsd"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> </ItemGroup> <ItemGroup> <Compile Include="api\Commands\CreateAndAddUnitCommand.cs" />
--- 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
--- a/api/WarFoundryLoader.cs Mon Mar 09 20:45:45 2009 +0000 +++ b/api/WarFoundryLoader.cs Thu Mar 12 21:35:17 2009 +0000 @@ -275,18 +275,26 @@ foreach (FileInfo file in gameSystemFiles.Keys) { + FileLoadFailure failure = null; + try { bool loaded = LoadObject(file, gameSystemFiles[file]); if (!loaded) { - fails.Add(new FileLoadFailure(file, "FileLoadFailed", "Failed to load {0} as Race using {1}")); + failure = new FileLoadFailure(file, "FileLoadFailed", "Failed to load {0} as Race using {1}"); } } catch (Exception ex) { - fails.Add(new FileLoadFailure(file, ex.Message)); + failure = new FileLoadFailure(file, ex.Message); + } + + if (failure!=null) + { + fails.Add(failure); + LogNotifier.Warn(GetType(), failure.Message); } } @@ -299,18 +307,26 @@ foreach (FileInfo file in raceFiles.Keys) { + FileLoadFailure failure = null; + try { bool loaded = LoadObject(file, raceFiles[file]); if (!loaded) { - fails.Add(new FileLoadFailure(file, "FileLoadFailed", "Failed to load {0} as Race using {1}")); + failure = new FileLoadFailure(file, "FileLoadFailed", "Failed to load {0} as Race using {1}"); } } catch (Exception ex) { - fails.Add(new FileLoadFailure(file, ex.Message)); + failure = new FileLoadFailure(file, ex.Message); + } + + if (failure!=null) + { + fails.Add(failure); + LogNotifier.Warn(GetType(), failure.Message); } }
--- a/dtds/race.xsd Mon Mar 09 20:45:45 2009 +0000 +++ b/dtds/race.xsd Thu Mar 12 21:35:17 2009 +0000 @@ -28,7 +28,7 @@ <xs:element name="requirements" type="requirementstype" /> <xs:element name="contains" type="containstype" /> <xs:element name="extraData" type="extradatatype" /> - <xs:element name="notes" type="xsd:string" /> + <xs:element name="notes" type="xs:string" /> </xs:all> <xs:attribute name="id" type="xs:ID" /> <xs:attribute name="typeName" type="xs:string" use="required"/> @@ -39,7 +39,7 @@ <xs:attribute name="maxNumber" type="core:infiniteOrNonNegativeInteger" default="-1"/> <xs:attribute name="minSize" type="core:positiveInteger" default="5"/> <xs:attribute name="maxSize" type="core:infiniteOrNonNegativeInteger" default="-1"/> - <xs:attribute name="baseSize" type="xsd:nonNegativeInteger" default="0"/> + <xs:attribute name="baseSize" type="xs:nonNegativeInteger" default="0"/> </xs:complexType> <xs:complexType name="statstype"> <xs:sequence> @@ -48,9 +48,10 @@ </xs:complexType> <xs:complexType name="stattype"> <xs:simpleContent> - <xs:extension base="xs:string"/> + <xs:extension base="xs:string"> + <xs:attribute name="name" type="xs:string" use="required"/> + </xs:extension> </xs:simpleContent> - <xs:attribute name="name" type="xs:string" use="required"/> </xs:complexType> <xs:complexType name="unitequipmenttype"> <xs:sequence> @@ -89,9 +90,10 @@ </xs:complexType> <xs:complexType name="requirementtype"> <xs:simpleContent> - <xs:extension base="xs:string"/> + <xs:extension base="xs:string"> + <xs:attribute name="requirementName" type="xs:string" use="required"/> + </xs:extension> </xs:simpleContent> - <xs:attribute name="requirementName" type="xs:string" use="required"/> </xs:complexType> <xs:complexType name="containstype"> <xs:sequence> @@ -108,9 +110,10 @@ </xs:complexType> <xs:complexType name="extradatadatatype"> <xs:simpleContent> - <xs:extension base="xs:string"/> + <xs:extension base="xs:string"> + <xs:attribute name="id" type="xs:ID" use="required"/> + </xs:extension> </xs:simpleContent> - <xs:attribute name="id" type="xs:ID" use="required"/> </xs:complexType> <xs:complexType name="equipmenttype"> <xs:sequence> @@ -119,7 +122,7 @@ </xs:complexType> <xs:complexType name="equipmentitemtype"> <xs:all> - <xs:element name="description" type="xsd:string" /> + <xs:element name="description" type="xs:string" /> </xs:all> <xs:attribute name="id" type="xs:ID" use="required"/> <xs:attribute name="name" type="xs:string" use="required"/> @@ -132,7 +135,7 @@ </xs:complexType> <xs:complexType name="equipmentitemtype"> <xs:all> - <xs:element name="description" type="xsd:string" /> + <xs:element name="description" type="xs:string" /> </xs:all> <xs:attribute name="id" type="xs:ID" use="required"/> <xs:attribute name="name" type="xs:string" use="required"/> @@ -140,7 +143,7 @@ <xs:attribute name="armoutType" type="armourtype" default="none"/> </xs:complexType> <xs:simpleType name="armourtype"> - <xs:restriction base="xsd:string"> + <xs:restriction base="xs:string"> <xs:enumeration value="None"/> <xs:enumeration value="Shield"/> <xs:enumeration value="LightArmour"/> @@ -162,7 +165,7 @@ </xs:complexType> <xs:complexType name="abilitytype"> <xs:all> - <xs:element name="description" type="xsd:string" /> + <xs:element name="description" type="xs:string" /> </xs:all> <xs:attribute name="id" type="xs:ID" use="required"/> <xs:attribute name="name" type="xs:string" use="required"/>
--- a/dtds/warfoundry-cats.xsd Mon Mar 09 20:45:45 2009 +0000 +++ b/dtds/warfoundry-cats.xsd Thu Mar 12 21:35:17 2009 +0000 @@ -1,6 +1,6 @@ <?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://ibboard.co.uk/warfoundry/cats" -xmlns="http://ibboard.co.uk/warfoundry/cats"elementFormDefault="qualified"> +xmlns="http://ibboard.co.uk/warfoundry/cats" elementFormDefault="qualified"> <xs:complexType name="categoriestype"> <xs:sequence> <xs:element name="cat" type="cattype" minOccurs="1" maxOccurs="unbounded"/>
--- a/dtds/warfoundry-core.xsd Mon Mar 09 20:45:45 2009 +0000 +++ b/dtds/warfoundry-core.xsd Thu Mar 12 21:35:17 2009 +0000 @@ -1,6 +1,6 @@ <?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://ibboard.co.uk/warfoundry/core" -xmlns="http://ibboard.co.uk/warfoundry/core"elementFormDefault="qualified"> +xmlns="http://ibboard.co.uk/warfoundry/core" elementFormDefault="qualified"> <xs:simpleType name="infiniteOrNonNegativeDecimal"> <xs:restriction base="xs:decimal"> <xs:minInclusive value="-1"/>