I'm trying to create a tool that can generate XSDs for the XAML produced by serializing a type in .NET, but this is not specifically .NET related.
Let's say I have a type. This type has properties and is a collection.
public class MyType : Collection<CollectedType>
{
public PType1 PropertyOne {get;set;}
public PType2 PropertyTwo {get;set;}
}
This serializes to the following (omitting the object graph construction):
<MyType xmlns="clr-namespace:blahblahblah">
<CollectedType name="First instance in the collection"/>
<CollectedType name="Second instance in the collection"/>
<MyType.PropertyOne>
<PType1 Value = "Serialized object in PropertyOne" />
</MyType.PropertyOne>
<MyType.PropertyTwo>
<PType2 Value = "Serialized object in PropertyTwo" />
</MyType. PropertyTwo >
</MyType>
In generating the XSD for this type, I can say the following:
- MyType is a complexType
- MyType will contain a reference to a group called CollectedTypeGroup
- CollectedTypeGroup contains CollectedType's element and elements for types that extend CollectedType
- MyType will contain an element called MyType.PropertyOne
- PType1 is another complexType
- MyType will contain an element called MyType.PropertyTwo
- PType2 is another complexType
This is all relatively easy to do. Here's a chunk of the generated xsd:
<xs:complexType name="MyType">
<xs:sequence>
<xs:element name="MyType.PropertyOne" type="PType1"/>
<xs:element name="MyType.PropertyOne" type="PType1"/>
<xs:group ref="CollectedTypeGroup"/>
</xs:sequence>
</xs:complexType>
Now comes the hard part. Because the XML will be mapped back to an object graph, I have a list of restrictions on how elements are added to MyType that MUST BE enforced by the schema. If these three requirements and only these three are not enforced, I face issues with users attempting to use my schema:
1) Elements added to MyType must not be restricted to a particular order
2) Elements that represent a property of my object can only appear once or not at all
3) Group elements must be unbounded; they can appear anywhere in the parent element and 0...* times
This is where I am having a horrendous time. I cannot find a satisfactory combination of choices, sequences, alls etc. to satisfy these three requirements. I have also tried placing the elements in a separate group, complexTypes, etc. Nothing seems to work.
How can I combine my elements and my groups into a single complexType and meet my three requirements?