I am writing a schema for EMF to describe general graphs. The problem is that if this is directed graph, then the edge should have properties of src_node and dst_node, otherwise it has node_one and node_two. I tried to use "choice" to have mutally exclusive elements but in EMF it functions the same as "sequence". e.g a similar problem for NodeProperty
<xsd:complexType name="NodeProperty">
<xsd:choice>
<xsd:element name="StringValue" type="xsd:string"/>
<xsd:element name="IntValue" type="xsd:int"/>
<xsd:element name="DoubleValue" type="xsd:double"/>
</xsd:choice>
<xsd:attribute name="Property" type="xsd:string"/>
</xsd:complexType>
Another problem in substitutionGroup is that src_node and dst_node are claimed be to unresolved by EMF. The complete code:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:simpleType name="GraphType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Directed"/>
<xsd:enumeration value="Undirected"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="NodeProperty">
<xsd:choice>
<xsd:element name="StringValue" type="xsd:string"/>
<xsd:element name="IntValue" type="xsd:int"/>
<xsd:element name="DoubleValue" type="xsd:double"/>
</xsd:choice>
<xsd:attribute name="Property" type="xsd:string"/>
</xsd:complexType>
<xsd:complexType name="Node">
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="0"
name="Node" type="lib:NodeProperty"/>
</xsd:sequence>
<xsd:attribute name="NodeName" type="xsd:string" />
</xsd:complexType>
<xsd:element name="src_node" type="xsd:anyURI" ecore:reference="lib:Node"/>
<xsd:element name="node_one" type="xsd:anyURI" substitutionGroup="src_node"/>
<xsd:element name="dst_node" type="xsd:anyURI" ecore:reference="lib:Node"/>
<xsd:element name="node_two" type="xsd:anyURI" substitutionGroup="dst_node"/>
<xsd:complexType name="Edge">
<xsd:sequence>
<xsd:element ref="src_node"/>
<xsd:element ref="dst_node"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="GeneralGraph">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="type" type="lib:GraphType"/>
<xsd:element name="NodeList">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="0"
name="Node" type="lib:Node"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="EdgeList">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" minOccurs="0"
name="Edge" type="lib:Edge"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
Yes. Substitution groups apply to global elements. So move your elements out of your type and reference to them in the type.
<xsd:element name="src_node" type="xsd:anyURI" ecore:reference="lib:Node"/>
<xsd:element name="node_one" type="xsd:anyURI" substitutionGroup="src_node"/>
<xsd:element name="dst_node" type="xsd:anyURI" ecore:reference="lib:Node"/>
<xsd:element name="node_two" type="xsd:anyURI" substitutionGroup="dst_node"/>
<xsd:complexType name="Edge">
<xsd:sequence>
<xsd:element ref="src_node"/>
<xsd:element ref="dst_node"/>
</xsd:sequence>
</xsd:complexType>
Untested.
The idea is that now node_one
could be used instead src_node
in Edge
and node_two
instead of node_two
.
Note that type of the substitutable must be derived from the type of the substitution group element. So I used anyURI
just for example. You'll probably want to rework it.
By the way I generally discourage usage of subsitition groups. Makes your XML unpredictable.