Reputation: 31416
What I'm trying to accomplish is the creation of an XML schema which describes an XML file which can take one of two forms. There's a section of common elements between the two and then a small section which differs. Something like:
<Dessert>
<Identifier> Hot Fudge Sundae </Identifier>
<SaleDate> 2013-06-03 </SaleDate>
<Duration> 2 </Duration>
<Size> SuperScooper </Size>
</Dessert>
<Dessert>
<Identifier> Dutch Apple Pie </Identifier>
<SaleDate> 2013-06-03 </SaleDate>
<Duration> 1 </Duration>
<AlaMode> 1 </AlaMode>
<IceCreamFlavor> Vanilla </IceCreamFlavor>
</Dessert>
So for the ice cream desserts there's just a Size while for the pies there's an AlaMode indicator and an IceCreamFlavor specifier.
What I want to accomplish is to use the xs:choice
specifier to indicate that the Dessert
XML will either have one or the other (Size
or AlaMode
and IceCreamFlavor
) so that I can validate them.
What I've tried to do is create two types and do something like this:
and then do something like:
<xs:choice>
<xs:element name="Sundae" type="SundaeType" />
<xs:element name="Pie" type="PieType" />
</xs:choice>
And but the resulting XML, of course, has a layout like so:
<Dessert>
<Identifier> Hot Fudge Sundae </Identifier>
<SaleDate> 2013-06-03 </SaleDate>
<Duration> 2 </Duration>
<Sundae>
<Size> SuperScooper </Size>
<Sundae>
</Dessert>
Which doesn't match the existing file structure.
I can simply make the union of all possible elements and do away with the xs:choice
stuff but that really doesn't convey the expectations of the format (that it is, for instance, not valid for the sundae to have an AlaMode
element).
Is there any way to accomplish this? I suspect if I had just one field different I could accomplish this with the xs:choice
(perhaps) and not have that additional level. Or maybe I'm just missing something here.
And yes, I realize that the layout isn't the best but it is an existing format that I can really change at this point.
Upvotes: 1
Views: 138
Reputation: 3237
If you don't mind imposing an order on the elements in the source documents you can make this work using xs:sequence:
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/XMLSchema.xsd"
xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="Dessert">
<xs:sequence>
<xs:element name="Identifier" type="xs:string"/>
<xs:element name="SaleDate" type="xs:int"/>
<xs:element name="Duration" type="xs:int"/>
<xs:choice>
<xs:element name="Size" type="xs:string"/>
<xs:sequence>
<xs:element name="AlaMode" type="xs:int"/>
<xs:element name="IceCreamFlavor" type="xs:string"/>
</xs:sequence>
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:element name="Dessert" type="Dessert"/>
</xs:schema>
Upvotes: 2