XML Schemaについて
Unityでゲーム内で実行されるイベントデータをXMLで管理しています。 このXMLの妥当性を検証するためのXML Schemaを書いてみたのでメモします。
まずXMLなのですが、大まかにこんな感じで使っています。
<?xml version="1.0" encoding="utf-8"?> <Events> <Event eventID='ev_st00_001'> <!--システム制御--> <SystemControl> <TimeStop>true</TimeStop> <Input> <DisableGroup>Player</DisableGroup> <DisableGroup>SwitchMenu</DisableGroup> </Input> </SystemControl> <!--会話--> <Conversation name='Charactor1'> <Text> イベント1会話テスト1 </Text> <Text> イベント1会話テスト2 </Text> </Conversation> <!--カメラ移動--> <TargetTraceCameraControl> <OffsetX>5</OffsetX> <OffsetY>5</OffsetY> <OffsetZ>5</OffsetZ> <Target>Cube</Target> </TargetTraceCameraControl> <!--会話--> <Conversation name='Charactor2'> <Text> イベント1会話テスト3 </Text> <Text> イベント1会話テスト4 </Text> </Conversation> <!--カメラ移動--> <TargetTraceCameraControl> <OffsetX>0</OffsetX> <OffsetY>4.5</OffsetY> <OffsetZ>-20</OffsetZ> <Target>Player</Target> </TargetTraceCameraControl> <!--システム制御--> <SystemControl> <TimeStop>false</TimeStop> <Input> <EnableGroup>Player</EnableGroup> <EnableGroup>SwitchMenu</EnableGroup> </Input> </SystemControl> </Event> <Event eventID='ev_st00_002'> <Conversation> <Text>イベント2会話テスト1</Text> </Conversation> </Event> </Events>
それぞれの要素がゲーム内で解釈されて該当するイベントを実行するのですが、 ここではそれぞれの要素の意味よりも、その構造を把握してください。
Events要素の中に1つのイベントを表すEventが複数入り、そのEvent要素にはSystemControl、Conversation、TargetTraceCameraControl等の要素が任意の順番で任意の個数入ります。以降は長くなるので説明を省きますが、図では以下のようになっています。
これに対するXML Schemaは以下のようになります。
<?xml version="1.0" encoding="utf-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <!--Events--> <xsd:element name="Events"> <xsd:complexType> <xsd:sequence> <xsd:element ref="Event" maxOccurs="unbounded"></xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <!--Event--> <xsd:element name="Event"> <xsd:complexType> <xsd:choice maxOccurs="unbounded"> <xsd:group ref="EachEvent"></xsd:group> </xsd:choice> <xsd:attribute name="eventID" type="xsd:string"></xsd:attribute> </xsd:complexType> </xsd:element> <!--AttributeGroup--> <xsd:attributeGroup name="SelectEventObjectAttribute"> <xsd:attribute name="name"></xsd:attribute> <xsd:attribute name="tag"></xsd:attribute> <xsd:attribute name="id"></xsd:attribute> </xsd:attributeGroup> <!-- ↓******************************EachEventDefinition*********************************↓ --> <!--EachEvent--> <xsd:group name="EachEvent"> <xsd:choice> <xsd:element ref="SystemControl"></xsd:element> <xsd:element ref="Conversation"></xsd:element> <xsd:element ref="TargetTraceCameraControl"></xsd:element> </xsd:choice> </xsd:group> <!--SystemControl--> <xsd:element name="SystemControl"> <xsd:complexType> <xsd:sequence> <xsd:choice minOccurs="0"> <xsd:element name="TimeStop" type="xsd:boolean"></xsd:element> </xsd:choice> <xsd:choice minOccurs="0"> <xsd:element ref="Input"></xsd:element> </xsd:choice> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="Input"> <xsd:complexType> <xsd:choice maxOccurs="unbounded"> <xsd:element name="EnableGroup" type="xsd:string"></xsd:element> <xsd:element name="DisableGroup" type="xsd:string"></xsd:element> </xsd:choice> </xsd:complexType> </xsd:element> <!--Conversation--> <xsd:element name="Conversation"> <xsd:complexType> <xsd:choice maxOccurs="unbounded"> <xsd:element name="Text" type="xsd:string"></xsd:element> </xsd:choice> <xsd:attributeGroup ref="SelectEventObjectAttribute"></xsd:attributeGroup> </xsd:complexType> </xsd:element> <!--TargetTraceCameraControl--> <xsd:element name="TargetTraceCameraControl"> <xsd:complexType> <xsd:sequence> <xsd:choice minOccurs="0"> <xsd:element name="OffsetX" type="xsd:float"></xsd:element> </xsd:choice> <xsd:choice minOccurs="0"> <xsd:element name="OffsetY" type="xsd:float"></xsd:element> </xsd:choice> <xsd:choice minOccurs="0"> <xsd:element name="OffsetZ" type="xsd:float"></xsd:element> </xsd:choice> <xsd:choice minOccurs="0"> <xsd:element name="Target" type="xsd:string"></xsd:element> </xsd:choice> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema>
XML Schemaに関しては以下で詳しく取り扱ってくださっています。
また、C#で妥当性検証をする場合、以下のように記述します。
private XElement GetElementFromXML() { XmlReaderSettings settings = new XmlReaderSettings(); settings.ValidationType = ValidationType.Schema; settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings; settings.Schemas.Add(GetXmlSchema()); using(var reader = XmlReader.Create("<XMLファイルパス>", settings)) { return XElement.Load(reader); } } private XmlSchema GetXmlSchema() { XmlSchema schema = new XmlSchema(); using(var reader = XmlReader.Create("<XSDファイルパス>")) schema = XmlSchema.Read(reader, null); return schema; }