tags:

views:

8

answers:

1

I'm working on an XSD. I'd like to have a container element (complex type) which contains any element whose base type is component.

One approach is...

<complexType name="Container">
    <sequence>
        <element name="Child" type="am:Component"></element>
    </sequence>
</complexType>

But the problem there is my components are called children. Lets assume I have 3 components, foo, bar, and baz. I'd like to be able to make a document that looked like...

<container>
    <foo fooTag="foo"/>
    <foo fooTag="foo"/>
    <baz bazTag="baz"/>
    <bar barTag="bar"/>
</container>

With the first approach I'd end up with...

<container>
    <child fooTag="foo"/>
    <child fooTag="foo"/>
    <child bazTag="baz"/>
    <child barTag="bar"/>
</container>

I could simply use an xs:any element but then I would lose my assertion that the child must be a component. Is there a way I can get what I want?

+1  A: 

Ultimately you need to be able to say "Type Foo is represented by an element named foo" and that's what the name attribute of xs:element does. You can't do outright abstraction (as you could in a programming language), because types are just definitions and don't have a specific element name until you give it one.

You will need to list out every possible subtype in your sequence.

<xs:sequence>
    <xs:choice>
         <xs:element name="type1" type="Type1" />
         <xs:element name="type2" type="Type2" />
         <xs:element name="type3" type="Type3" />
         <xs:element name="type4" type="Type4" />
    </xs:choice>
</xs:sequence>

You can also define your element names globally and refer to them like so, but ultimately you still need to indicate which child element names are valid inside your container element.

<xs:sequence>
    <xs:any>
         <xs:element ref="type1" />
         <xs:element ref="type2" />
         <xs:element ref="type3" />
         <xs:element ref="type4" />
    </xs:any>
</xs:sequence>

And elsewhere:

<xs:element name="type1" type="Type1" />
<xs:element name="type2" type="Type2" />
<xs:element name="type3" type="Type3" />
<xs:element name="type4" type="Type4" />
Adam Sills
I was afraid of that. Thanks for the nice answer and examples.
Pace
Yeah... unfortunately that behavior is counter-intuitive to anyone coming from a programming point of view. Though this limitation is evidenced in .NET web services for instance - the WSDL generator isn't smart enough to be able to handle subtypes unless you explicitly tell it what subtypes of a given type are valid (via the XmlIncludeAttribute).
Adam Sills