(This is not exactly an answer to OP, but an answer to another suggested answer to OP's question. As a quite new memeber, I'm not sure if this breaks some rules or conventions here on stackoverflow.com. Sorry.)
As user @Richard wrote in his answer:
Unfortunately there is no way in XML Schema to define "this set of child elements in any order but each occurs at least once".
You are stuck with either a defined order, or one of a set (possibly repeated).
It is correct that there is no tags or attributes that especially allows such structures, however the quoted text is theoretically not true, although the solution becomes quickly huge as the amount of elements grows. Writing a schema for such structure with several elements is laborious, error-prone and difficult to maintain. So even though a solution exists, practically implementing it is not possible or worth it.
Original posters question had a set of only three randomly occurring elements. Correct solution was simple, because none of the elements was mandatory. But even in that kind of case, with such a small set of elements, forcing each one of the elements to appear at least once is still moderately easy to implement. Code example below
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Schema for 3 elements with random order.
Each element must appear at least once. -->
<xs:element name="Association" type="xs:string"/>
<xs:element name="Message" type="xs:string"/>
<xs:element name="Sequence" type="xs:string"/>
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="Connectors" type="unordered-3-group" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="unordered-3-group">
<!-- state level 0 -->
<xs:group ref="Connectors-state-0"/>
</xs:complexType>
<xs:group name="Connectors-state-0">
<xs:sequence>
<!-- Empty, no previous elements
<xs:choice minOccurs="0" maxOccurs="unbounded">
</xs:choice> -->
<xs:choice>
<xs:sequence>
<xs:element ref="Association"/>
<xs:group ref="Connectors-state-1a"/>
</xs:sequence>
<xs:sequence>
<xs:element ref="Message"/>
<xs:group ref="Connectors-state-1b"/>
</xs:sequence>
<xs:sequence>
<xs:element ref="Sequence"/>
<xs:group ref="Connectors-state-1c"/>
</xs:sequence>
</xs:choice>
</xs:sequence>
</xs:group>
<xs:group name="Connectors-state-1a">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="Association"/>
</xs:choice>
<xs:choice>
<xs:sequence>
<xs:element ref="Message" />
<xs:group ref="Connectors-state-2a"/>
</xs:sequence>
<xs:sequence>
<xs:element ref="Sequence" />
<xs:group ref="Connectors-state-2b"/>
</xs:sequence>
</xs:choice>
</xs:sequence>
</xs:group>
<xs:group name="Connectors-state-1b">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="Message"/>
</xs:choice>
<xs:choice>
<xs:sequence>
<xs:element ref="Association" />
<xs:group ref="Connectors-state-2a"/>
</xs:sequence>
<xs:sequence>
<xs:element ref="Sequence" />
<xs:group ref="Connectors-state-2c"/>
</xs:sequence>
</xs:choice>
</xs:sequence>
</xs:group>
<xs:group name="Connectors-state-1c">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="Sequence"/>
</xs:choice>
<xs:choice>
<xs:sequence>
<xs:element ref="Association" />
<xs:group ref="Connectors-state-2b"/>
</xs:sequence>
<xs:sequence>
<xs:element ref="Message" />
<xs:group ref="Connectors-state-2c"/>
</xs:sequence>
</xs:choice>
</xs:sequence>
</xs:group>
<xs:group name="Connectors-state-2a">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="Association"/>
<xs:element ref="Message"/>
</xs:choice>
<xs:choice>
<xs:sequence>
<xs:element ref="Sequence" />
<xs:group ref="Connectors-state-3a"/>
</xs:sequence>
</xs:choice>
</xs:sequence>
</xs:group>
<xs:group name="Connectors-state-2b">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="Association"/>
<xs:element ref="Sequence"/>
</xs:choice>
<xs:choice>
<xs:sequence>
<xs:element ref="Message" />
<xs:group ref="Connectors-state-3a"/>
</xs:sequence>
</xs:choice>
</xs:sequence>
</xs:group>
<xs:group name="Connectors-state-2c">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="Message"/>
<xs:element ref="Sequence"/>
</xs:choice>
<xs:choice>
<xs:sequence>
<xs:element ref="Association" />
<xs:group ref="Connectors-state-3a"/>
</xs:sequence>
</xs:choice>
</xs:sequence>
</xs:group>
<xs:group name="Connectors-state-3a">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="Association"/>
<xs:element ref="Message"/>
<xs:element ref="Sequence"/>
</xs:choice>
<!-- Empty, no new elements
<xs:choice>
<xs:sequence>
</xs:sequence>
</xs:choice> -->
</xs:sequence>
</xs:group>
</xs:schema>
Connectors
is used as a container just like OP had. Separate root
element allows multiple Connector
s only to make testing different combinations a bit easier.
Imitating different states with group elements
I have edited this answer and updated the code. New one is longer but it is a quite clear example of making use of state-based schema design. Code follows the different phases of a finite state machine that can validate this problem. All states are represented as <xs:group>
elements and each group references other groups that represent all possible following states. All the <xs:group>
elements obey same rules for their structure. The groups have a sequence of two choices. The first <xs:choice>
is an unbounded repetition of the already seen elements. The second <xs:choice>
contains sequences of all the possible new elements following a reference to a group that represents the next state.
Complexity of the problem
Case of N elements can be validated with a deterministic finite state machine that has 2^N different states (including the initial state). States will form N different levels and amount of states on each level corresponds to binomial coefficients i.e. amount of states on different levels is "n over k" where "n" represents the number of different elements and "k" represents the depth of level. Because adding one more element doubles the amount of needed states it also doubles the number of <xs:group>
s and thus roughly doubles the LOC for this complex type.
Is there any use for this?
Maybe... or not. Manually writing and especially updating such structure for large element sets is probably unreasonable. However since all the groups have similar structure it should be relatively easy to programmatically generate appropriate XML Schema code for the whole complexType
structure. One way to do this that comes into my mind is a function that takes two lists as parameters, seen and unseen elements and then adds all the seen elements to the first <xs:choice>
element and for each unseen element creates a transition to appropriate new state and then calls itself for every new referenced state.
Bear in mind that even if generating code takes away the pain of manually keeping track of the whole structure, on large element sets the code size will grow so big that the size is no more reasonable. A set of 14 elements requires 2^14 = 16383 groups and at depth level 7 there is a maximum of (14 over 7) = 3432 parallel state groups, each group having 39 elements (= slightly over 40 LOC). No, you don't want anything like that. In such cases you should start looking for some other suitable schema definition language.