Using XSD, I want to define a complex element which can appear in three different forms:
<Scope Name="foo" /> <!-- no children -->
<Scope Name="foo" Src="bar" /> <!-- When Src is present, there must be no children! -->
<Scope Name="foo"><!-- other children --></Scope>
In the third case, it is well defined what may appear as children elements (e.g. all three types of “Scope”). The important part is that a Scope element with a “Src” attribute must be empty!
Furhtermore, in different places, I want only specific types of elements allowed. For example, inside the root tag, I want to allow exactly one Scope element of the third type; in most cases I wand to allow all cases. And that’s the problem: How to solve this?
What I did so far: I created a complex type for each of the 3 cases which I can use within . However, I can’t use:
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Scope" type="type_Scope_WithSrc" />
<xs:element name="Scope" type="type_Scope_WithContent" />
<xs:element name="Scope" type="type_Scope_Base" />
</xs:choice>
I tried to create a union of those, but unions are only allowed for simpleTypes.
I also tried to define an overall type “type_Scope” which uses xs:choice to include them. But xs:choice would include xs:elements which would also require a name in this case 🙁
Can you tell me how I can handle this?
Please do not tell me that it is not possible with XSD 🙁 🙁
Thank you
Regards
divB
You may get different answers, depending on whether you want to achieve this with XSD 1.1 or XSD 1.0; I would assume that you’re after a 1.0 solution, which I will describe here (I don’t believe 1.1 is practical yet).
If you want to preserve the element name, and vary its content, your only option here is to employ xsi:type. Instead of a choice, just use a single Scope element; make its type a complex type, with an attribute named “Name”. Have the other two types extend from this base type. And you’re done.
Note: I used a base abstract type as a mechanism to inform people that other types are expected to go in there; reality is it’ll work even without it, by using a type_Scope_Base right from the beginning.
XSD:
These are three sample XMLs, all valid. The first one with content model from
type_Scope_Base.This with content model from
type_Scope_WithSrc.And this with content model from
type_Scope_WithContent.If you want to allow for variation in the tag name, instead of a choice you could place there the head of a substitution group, which could at least give you a solution without xsi:type.
And then there are XSD 1.1 based solutions, but I would stay away from anything like that in an open environment; not everyone today has a compliant processor, let alone the spec itself is not a recommendation yet.