changeset 239:7c14537d4a23

Re #152: Test and fix extensibility of current schemas * Split out some reusable parts of Race schema * Replace use of "xs:all" with "xs:sequence" * Replace use of "core:extension" with standard "xs:any" * Start to use xs:key and xs:keyref to get more built-in validation
author IBBoard <dev@ibboard.co.uk>
date Tue, 23 Feb 2010 21:00:23 +0000
parents d1068f4b6d1c
children 38a4154c4537
files schemas/race.xsd schemas/system.xsd
diffstat 2 files changed, 180 insertions(+), 168 deletions(-) [+]
line wrap: on
line diff
--- a/schemas/race.xsd	Sun Feb 21 20:25:52 2010 +0000
+++ b/schemas/race.xsd	Tue Feb 23 21:00:23 2010 +0000
@@ -3,183 +3,26 @@
 targetNamespace="http://ibboard.co.uk/warfoundry/race" xmlns="http://ibboard.co.uk/warfoundry/race" elementFormDefault="qualified">
 <xs:element name="race">
 	<xs:complexType>
-		<xs:all>
+		<xs:sequence>
 			<xs:element name="units">
 				<xs:complexType>
 					<xs:sequence>
-						<xs:element name="unit" maxOccurs="unbounded">
-							<xs:complexType>
-								<xs:all>
-									<xs:element name="stats">
-										<xs:complexType>
-											<xs:sequence>
-												<xs:element name="stat" maxOccurs="unbounded">
-													<xs:complexType>
-														<xs:simpleContent>
-															<xs:extension base="xs:string">
-																<xs:attribute name="name" type="xs:string" use="required"/>
-																<xs:anyAttribute/>
-															</xs:extension>
-														</xs:simpleContent>
-													</xs:complexType>
-												</xs:element>
-											</xs:sequence>
-											<xs:attribute name="statSet" type="xs:string" default="" />
-											<xs:anyAttribute/>
-										</xs:complexType>
-									</xs:element>
-									<xs:element name="equipmentSlots" minOccurs="0">
-										<xs:complexType>
-											<xs:sequence>
-												<xs:element name="equipmentSlot" maxOccurs="unbounded">
-													<xs:complexType>
-														<xs:all>
-															<xs:element name="maxLimit" minOccurs="0" type="core:limit" />
-															<xs:element ref="core:extension" minOccurs="0" />													
-														</xs:all>
-														<xs:attribute name="name" type="xs:string" use="required"/>
-														<xs:anyAttribute/>
-													</xs:complexType>
-												</xs:element>
-											</xs:sequence>
-										</xs:complexType>
-									</xs:element>
-									<xs:element name="unitEquipment" minOccurs="0">
-										<xs:complexType>
-											<xs:sequence>
-												<xs:element name="unitEquipmentItem" maxOccurs="unbounded">
-													<xs:complexType>
-														<xs:all>
-															<xs:element name="minLimit" minOccurs="0" type="core:limit" />
-															<xs:element name="maxLimit" minOccurs="0" type="core:limit" />
-															<xs:element ref="core:extension" minOccurs="0" />
-														</xs:all>
-														<xs:attribute name="id" type="xs:IDREF" />
-														<xs:attribute name="required" type="xs:boolean" default="false"/>
-														<!-- exclusivityGroup is deprecated in favour of the comma-separated exclusivityGroups -->
-														<xs:attribute name="exclusivityGroup" type="xs:string" default=""/>
-														<xs:attribute name="exclusivityGroups" type="xs:string" default=""/>
-														<xs:attribute name="equipmentSlot" type="xs:string"/>
-														<xs:attribute name="roundDirection" type="core:updowntype" default="up"/>
-														<xs:attribute name="costMultiplier" type="core:nonNegativeDouble" default="1"/>
-														<xs:attribute name="costRounding" type="costroundingtype" default="UpToHalf"/>
-														<xs:anyAttribute/>
-													</xs:complexType>
-												</xs:element>
-											</xs:sequence>
-											<xs:anyAttribute/>
-										</xs:complexType>
-									</xs:element>
-									<xs:element name="unitAbilities" minOccurs="0">
-										<xs:complexType>
-											<xs:sequence>
-												<xs:element name="unitAbility" maxOccurs="unbounded">
-													<xs:complexType>
-														<xs:attribute name="abilityID" type="xs:IDREF" />
-														<xs:attribute name="required" type="xs:boolean" default="true"/>
-														<xs:anyAttribute/>
-													</xs:complexType>
-												</xs:element>
-											</xs:sequence>
-											<xs:anyAttribute/>
-										</xs:complexType>
-									</xs:element>
-									<xs:element name="requirements" minOccurs="0">
-										<xs:complexType>
-											<xs:sequence>
-												<xs:element name="requirement">
-													<xs:complexType>
-														<xs:simpleContent>
-															<xs:extension base="xs:string">
-																<xs:attribute name="requirementName" type="xs:string" use="required"/>
-																<xs:anyAttribute/>
-															</xs:extension>
-														</xs:simpleContent>
-													</xs:complexType>
-												</xs:element>
-											</xs:sequence>
-											<xs:anyAttribute/>
-										</xs:complexType>
-									</xs:element>
-									<xs:element name="contains" minOccurs="0">
-										<xs:complexType>
-											<xs:sequence>
-												<xs:element name="containedUnit" maxOccurs="unbounded">
-													<xs:complexType>
-														<xs:attribute name="containedID" type="xs:IDREF" use="required"/>
-														<xs:anyAttribute/>
-													</xs:complexType>
-												</xs:element>
-											</xs:sequence>
-											<xs:anyAttribute/>
-										</xs:complexType>
-									</xs:element>
-									<xs:element name="extraData" minOccurs="0">
-										<xs:complexType>
-											<xs:sequence>
-												<xs:element name="data">
-													<xs:complexType>
-														<xs:simpleContent>
-															<xs:extension base="xs:string">
-																<xs:attribute name="id" type="xs:ID" use="required"/>
-																<xs:anyAttribute/>
-															</xs:extension>
-														</xs:simpleContent>
-													</xs:complexType>
-												</xs:element>
-											</xs:sequence>
-											<xs:anyAttribute/>
-										</xs:complexType>
-									</xs:element>
-									<xs:element name="notes" type="xs:string" minOccurs="0" />
-									<xs:element ref="core:extension" minOccurs="0" />
-								</xs:all>
-								<xs:attribute name="id" type="xs:ID" />
-								<xs:attribute name="typeName" type="xs:string" use="required"/>
-								<xs:attribute name="cat" type="xs:string" use="required"/>
-								<xs:attribute name="points" type="core:nonNegativeNonInfiniteDouble" use="required"/>
-								<xs:attribute name="basePoints" type="core:nonNegativeNonInfiniteDouble" default="0"/>
-								<xs:attribute name="baseSize" type="xs:nonNegativeInteger" default="0"/>
-								<xs:attribute name="minSize" type="xs:nonNegativeInteger" default="5"/>
-								<xs:attribute name="maxSize" type="core:positiveOrInfiniteInteger" default="-1"/>
-								<xs:attribute name="minNum" type="xs:nonNegativeInteger" default="0"/>
-								<xs:attribute name="maxNum" type="core:positiveOrInfiniteInteger" default="-1"/>
-								<xs:anyAttribute/>
-							</xs:complexType>
-						</xs:element>
+						<xs:element name="unit" maxOccurs="unbounded" type="unit"/>
 					</xs:sequence>
 				</xs:complexType>
 			</xs:element>
 			<xs:element name="categories" type="cats:categoriestype" minOccurs="0" />
-			<xs:element name="equipment" minOccurs="0">
-				<xs:complexType>
-					<xs:sequence>
-						<xs:element name="equipmentItem" maxOccurs="unbounded">
-							<xs:complexType>
-								<xs:all>
-									<xs:element name="description" type="xs:string" minOccurs="0" />
-									<xs:element ref="core:extension" minOccurs="0" />
-								</xs:all>
-								<xs:attribute name="id" type="xs:ID" use="required"/>
-								<xs:attribute name="name" type="xs:string" use="required"/>
-								<xs:attribute name="cost" type="core:nonNegativeNonInfiniteDouble" use="required"/>
-								<xs:attribute name="armourType" type="armourtype" default="None"/>
-								<xs:anyAttribute/>
-							</xs:complexType>
-						</xs:element>
-					</xs:sequence>
-					<xs:anyAttribute/>
-				</xs:complexType>
+			<xs:element name="equipment" minOccurs="0" type="equipment">
 			</xs:element>
 			<xs:element name="abilities" minOccurs="0">
 				<xs:complexType>
 					<xs:sequence>
 						<xs:element name="ability" maxOccurs="unbounded">
 							<xs:complexType>
-								<xs:all>
+								<xs:sequence>
 									<xs:element name="description" type="xs:string" />
-									<xs:element ref="core:extension" minOccurs="0" />
-								</xs:all>
+									<xs:any minOccurs="0" maxOccurs="unbounded"/>
+								</xs:sequence>
 								<xs:attribute name="id" type="xs:ID" use="required"/>
 								<xs:attribute name="name" type="xs:string" use="required"/>
 								<xs:anyAttribute/>
@@ -189,8 +32,8 @@
 					<xs:anyAttribute/>
 				</xs:complexType>
 			</xs:element>
-			<xs:element ref="core:extension" minOccurs="0" />
-		</xs:all>
+			<xs:any minOccurs="0" maxOccurs="unbounded"/>
+		</xs:sequence>
 		<xs:attribute name="id" type="xs:ID" />
 		<xs:attribute name="subid" type="xs:string" default=""/>
 		<xs:attribute name="name" type="xs:string" use="required"/>
@@ -198,6 +41,175 @@
 		<xs:anyAttribute/>
 	</xs:complexType>
 </xs:element>
+
+<!--Reusable complex types -->
+<xs:complexType name="unit">
+	<xs:sequence>
+		<xs:element name="stats" type="stats"/>
+		<xs:element name="equipmentSlots" minOccurs="0">
+			<xs:complexType>
+				<xs:sequence>
+					<xs:element name="equipmentSlot" maxOccurs="unbounded">
+						<xs:complexType>
+							<xs:sequence>
+								<xs:element name="maxLimit" minOccurs="0" type="core:limit" />
+								<xs:any minOccurs="0" maxOccurs="unbounded"/>													
+							</xs:sequence>
+							<xs:attribute name="name" type="xs:string" use="required"/>
+							<xs:anyAttribute/>
+						</xs:complexType>
+					</xs:element>
+				</xs:sequence>
+			</xs:complexType>
+			<xs:key name="equipSlotName">
+				<xs:selector xpath="equipmentSlot"/>
+				<xs:field xpath="@name"/>
+			</xs:key>
+		</xs:element>
+		<xs:element name="unitEquipment" minOccurs="0">
+			<xs:complexType>
+				<xs:sequence>
+					<xs:element name="unitEquipmentItem" maxOccurs="unbounded">
+						<xs:complexType>
+							<xs:sequence>
+								<xs:element name="minLimit" minOccurs="0" type="core:limit" />
+								<xs:element name="maxLimit" minOccurs="0" type="core:limit" />
+								<xs:any minOccurs="0" maxOccurs="unbounded"/>
+							</xs:sequence>
+							<xs:attribute name="id" type="xs:IDREF" />
+							<xs:attribute name="required" type="xs:boolean" default="false"/>
+							<!-- exclusivityGroup is deprecated in favour of the comma-separated exclusivityGroups -->
+							<xs:attribute name="exclusivityGroup" type="xs:string" default=""/>
+							<xs:attribute name="exclusivityGroups" type="xs:string" default=""/>
+							<xs:attribute name="equipmentSlot" type="xs:string"/>
+							<xs:attribute name="roundDirection" type="core:updowntype" default="up"/>
+							<xs:attribute name="costMultiplier" type="core:nonNegativeDouble" default="1"/>
+							<xs:attribute name="costRounding" type="costroundingtype" default="UpToHalf"/>
+							<xs:anyAttribute/>
+						</xs:complexType>
+						<xs:keyref name="equipmentSlot" refer="equipSlotName">
+							<xs:selector xpath="."/>
+							<xs:field xpath="@equipmentSlot"/>
+						</xs:keyref>
+					</xs:element>
+				</xs:sequence>
+				<xs:anyAttribute/>
+			</xs:complexType>
+		</xs:element>
+		<xs:element name="unitAbilities" minOccurs="0">
+			<xs:complexType>
+				<xs:sequence>
+					<xs:element name="unitAbility" maxOccurs="unbounded">
+						<xs:complexType>
+							<xs:attribute name="abilityID" type="xs:IDREF" />
+							<xs:attribute name="required" type="xs:boolean" default="true"/>
+							<xs:anyAttribute/>
+						</xs:complexType>
+					</xs:element>
+				</xs:sequence>
+				<xs:anyAttribute/>
+			</xs:complexType>
+		</xs:element>
+		<xs:element name="requirements" minOccurs="0">
+			<xs:complexType>
+				<xs:sequence>
+					<xs:element name="requirement">
+						<xs:complexType>
+							<xs:simpleContent>
+								<xs:extension base="xs:string">
+									<xs:attribute name="requirementName" type="xs:string" use="required"/>
+									<xs:anyAttribute/>
+								</xs:extension>
+							</xs:simpleContent>
+						</xs:complexType>
+					</xs:element>
+				</xs:sequence>
+				<xs:anyAttribute/>
+			</xs:complexType>
+		</xs:element>
+		<xs:element name="contains" minOccurs="0">
+			<xs:complexType>
+				<xs:sequence>
+					<xs:element name="containedUnit" maxOccurs="unbounded">
+						<xs:complexType>
+							<xs:attribute name="containedID" type="xs:IDREF" use="required"/>
+							<xs:anyAttribute/>
+						</xs:complexType>
+					</xs:element>
+				</xs:sequence>
+				<xs:anyAttribute/>
+			</xs:complexType>
+		</xs:element>
+		<xs:element name="extraData" minOccurs="0">
+			<xs:complexType>
+				<xs:sequence>
+					<xs:element name="data" maxOccurs="unbounded">
+						<xs:complexType>
+							<xs:simpleContent>
+								<xs:extension base="xs:string">
+									<xs:attribute name="id" type="xs:ID" use="required"/>
+									<xs:anyAttribute/>
+								</xs:extension>
+							</xs:simpleContent>
+						</xs:complexType>
+					</xs:element>
+				</xs:sequence>
+				<xs:anyAttribute/>
+			</xs:complexType>
+		</xs:element>
+		<xs:element name="notes" type="xs:string" minOccurs="0" />
+		<xs:any minOccurs="0" maxOccurs="unbounded"/>
+	</xs:sequence>
+	<xs:attribute name="id" type="xs:ID" />
+	<xs:attribute name="typeName" type="xs:string" use="required"/>
+	<xs:attribute name="cat" type="xs:string" use="required"/>
+	<xs:attribute name="points" type="core:nonNegativeNonInfiniteDouble" use="required"/>
+	<xs:attribute name="basePoints" type="core:nonNegativeNonInfiniteDouble" default="0"/>
+	<xs:attribute name="baseSize" type="xs:nonNegativeInteger" default="0"/>
+	<xs:attribute name="minSize" type="xs:nonNegativeInteger" default="5"/>
+	<xs:attribute name="maxSize" type="core:positiveOrInfiniteInteger" default="-1"/>
+	<xs:attribute name="minNum" type="xs:nonNegativeInteger" default="0"/>
+	<xs:attribute name="maxNum" type="core:positiveOrInfiniteInteger" default="-1"/>
+	<xs:anyAttribute/>
+</xs:complexType>
+
+<xs:complexType name="stats">
+	<xs:sequence>
+		<xs:element name="stat" maxOccurs="unbounded">
+			<xs:complexType>
+				<xs:simpleContent>
+					<xs:extension base="xs:string">
+						<xs:attribute name="name" type="xs:string" use="required"/>
+						<xs:anyAttribute/>
+					</xs:extension>
+				</xs:simpleContent>
+			</xs:complexType>
+		</xs:element>
+	</xs:sequence>
+	<xs:attribute name="statSet" type="xs:string" default="" />
+	<xs:anyAttribute/>
+</xs:complexType>
+
+<xs:complexType name="equipment">
+	<xs:sequence>
+		<xs:element name="equipmentItem" maxOccurs="unbounded">
+			<xs:complexType>
+				<xs:sequence>
+					<xs:element name="description" type="xs:string" minOccurs="0" />
+					<xs:any minOccurs="0" maxOccurs="unbounded"/>
+				</xs:sequence>
+				<xs:attribute name="id" type="xs:ID" use="required"/>
+				<xs:attribute name="name" type="xs:string" use="required"/>
+				<xs:attribute name="cost" type="core:nonNegativeNonInfiniteDouble" use="required"/>
+				<xs:attribute name="armourType" type="armourtype" default="None"/>
+				<xs:anyAttribute/>
+			</xs:complexType>
+		</xs:element>
+	</xs:sequence>
+	<xs:anyAttribute/>
+</xs:complexType>
+
+<!--Reusable simple types -->
 <xs:simpleType name="costroundingtype">
 	<xs:restriction base="xs:string">
 		<xs:enumeration value="Up"/>
--- a/schemas/system.xsd	Sun Feb 21 20:25:52 2010 +0000
+++ b/schemas/system.xsd	Tue Feb 23 21:00:23 2010 +0000
@@ -3,7 +3,7 @@
 targetNamespace="http://ibboard.co.uk/warfoundry/system" xmlns="http://ibboard.co.uk/warfoundry/system" elementFormDefault="qualified">
 <xs:element name="system">
 	<xs:complexType>
-		<xs:all>
+		<xs:sequence>
 			<xs:element name="categories" type="cats:categoriestype"/>
 			<xs:element name="sysStatsList">
 				<xs:complexType>
@@ -27,8 +27,8 @@
 					<xs:anyAttribute/>
 				</xs:complexType>
 			</xs:element>
-			<xs:element ref="core:extension" minOccurs="0" />
-		</xs:all>
+			<xs:any minOccurs="0" maxOccurs="unbounded"/>
+		</xs:sequence>
 		<xs:attribute name="id" type="xs:ID" />
 		<xs:attribute name="name" type="xs:string" use="required"/>
 		<xs:attribute name="warn" type="xs:boolean" default="false"/>