Hello I came across a problem regarding to restrict the occurrence of an element according to its position in the document. Actually "position" might not be a proper term but I couldn't think of a better way to summarise the problem. Anyway let me explain a bit about the business logic. The schema will be designed for a play script. In a play, one actor can play multiple roles. A play contains many scenes, in a scene, there are several occurrences of stage-direction(Enter/Exit), between two stage-directions, actors give speeches. A sample xml instance would look like this:
<PLAY>
<CAST>
<ROLE>
<ACTOR id="1">Alex</ACTOR>
<PERSONA>Superman</PERSONA>
</ROLE>
<ROLE>
<ACTOR id="1">Alex</ACTOR>
<PERSONA>Batman</PERSONA>
</ROLE>
<ROLE>
<ACTOR id="2">John</ACTOR>
<PERSONA>Hulk</PERSONA>
</ROLE>
</CAST>
<TITLE>Lego Movie</TITLE>
<SCENE>
<TITLE>SCENE I</TITLE>
<STAGEDIR>Enter Superman, Hulk</STAGEDIR>
<SPEECH>
<SPEAKER actorID="1">Superman</SPEAKER>
<LINE>Hahaha</LINE>
</SPEECH>
<SPEECH>
<SPEAKER actorID="2">Hulk</SPEAKER>
<LINE>Hahaha</LINE>
</SPEECH>
<STAGEDIR>Exit Superman, Enter Batman</STAGEDIR>
<SPEECH>
<SPEAKER actorID="1">Batman</SPEAKER>
<LINE>Yo</LINE>
</SPEECH>
<SPEECH>
<SPEAKER actorID="2">Hulk</SPEAKER>
<LINE>Yo</LINE>
</SPEECH>
</SCENE>
</PLAY>
The restriction required here is that if an actor is playing multiple roles, it is not allowed for two persona to be talking to each other on the stage at the same time (if an actor is playing multiple roles, an actor's persona cannot appear on the stage at the same time). For example Alex is playing both Superman and Batman, they cannot appear on the stage at the same time since they are played by a same person. Currently the schema looks like:
<xs:complexType name="PLAYTYPE">
<xs:sequence>
<xs:element ref="CAST"/>
<xs:element ref="TITLE"/>
<xs:element ref="SCENE"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="CASTTYPE">
<xs:sequence>
<xs:element ref="ROLE" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ROLETYPE">
<xs:sequence>
<xs:element ref="ACTOR"/>
<xs:element ref="PERSONA"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SCENETYPE">
<xs:sequence>
<xs:element ref="TITLE"/>
<xs:element ref="STAGEDIR"/>
<xs:element ref="SPEECH" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ACTORTYPE">
<xs:sequence>
<xs:element ref="NAME"/>
</xs:sequence>
<xs:attributeGroup ref="attlist.ACTOR"/>
</xs:complexType>
<xs:complexType name="STAGEDIRTYPE" mixed="true">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="unbounded" ref="PERSONA"/>
</xs:sequence>
<xs:attributeGroup ref="attlist.SPEAKER"/>
</xs:complexType>
<xs:complexType name="SPEECHTYPE">
<xs:sequence>
<xs:element ref="SPEAKER"/>
<xs:element ref="LINE"/>
</xs:sequence>
<xs:attributeGroup ref="attlist.ACTOR"/>
</xs:complexType>
<xs:complexType name="SPEAKERTYPE" mixed="true">
<xs:attributeGroup ref="attlist.SPEAKER"/>
</xs:complexType>
<xs:element name="PLAY" type="PLAYTYPE"/>
<xs:element name="CAST" type="CASTTYPE"/>
<xs:element name="ROLE" type="ROLETYPE"/>
<xs:element name="ACTOR" type="ACTORTYPE"/>
<xs:element name="SCENE" type="SCENETYPE"/>
<xs:element name="STAGEDIR" type="STAGEDIRTYPE"/>
<xs:element name="SPEAKER" type="SPEAKERTYPE"/>
<xs:element name="TITLE" type="xs:string"/>
<xs:element name="PERSONA" type="xs:string"/>
<xs:element name="NAME" type="xs:string"/>
<xs:element name="LINE" type="xs:string"/>
<xs:attributeGroup name="attlist.ACTOR">
<xs:attribute name="id" use="required"/>
</xs:attributeGroup>
<xs:attributeGroup name="attlist.SPEAKER">
<xs:attribute name="actorID" use="required"/>
</xs:attributeGroup>
So how to achieve this kind of restriction in the schema?