Reputation: 6490
I am struggling with a xsd where I want to combine a xs:group
and a xs:all
entry:
Sample XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This group will be reused later -->
<xs:group name="TGroup">
<xs:choice>
<xs:element name="Mixable1" type="xs:string" />
<xs:element name="Mixable2" type="xs:string" />
<xs:element name="Mixable3" type="xs:string" />
</xs:choice>
</xs:group>
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:group ref="TGroup" minOccurs="0" maxOccurs="unbounded" />
<xs:all>
<xs:element name="RootContent1" type="xs:string" minOccurs="0" />
<xs:element name="RootContent2" type="xs:string" minOccurs="0" />
</xs:all>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
(this does not validate as xs:all
is not allowed in xs:sequence
)
What I am trying to achieve:
The root
element should always allow RootContent1
and RootContent2
in an arbitrary order (therefore the xs:all
) and each element should additionally be optional but would still allow all if necessary (in contrast to xs:choice
)
Furthermore I need a reusable set of nodes (defined by the group TGroup
) with an arbitrary amount of MixableX
elements in any order. It is a xs:group
because the group itself will be reused (in the real xsd) and I want to avoid duplication of declaration.
Some Sample XMLs
<root>
<Mixable1 />
</root>
<root>
<Mixable2 />
<RootContent1 />
</root>
<root>
<Mixable2 />
<Mixable1 />
<Mixable2 />
<RootContent2 />
</root>
I have the feeling that what I want to describe is non-deterministic for the parser and therefore not representable with XSD but I might as well just missed something.
Upvotes: 2
Views: 3686
Reputation: 3020
If you check this out : http://www.w3schools.com/schema/el_sequence.asp You will see that you are not allowed to nest xs:all inside of xs:sequence.
Also I tried tricking it by creating a group to contain the tag, but as it appears, (and also referenced in this post : XML Schema: all, sequence & groups)
XML Schema stipulates that an all group must appear as the sole child at the top of a content model.
But, if you don't plan on having RootContent1 & 2 simulatenously, then Filburt is right and you could simply go with another choice element:
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:group ref="TGroup" minOccurs="0" maxOccurs="unbounded"/>
<xs:choice minOccurs="0">
<xs:element name="RootContent1" type="xs:string" minOccurs="0"/>
<xs:element name="RootContent2" type="xs:string" minOccurs="0"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
Edit: This could be a work around for this specific case
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:group ref="TGroup" minOccurs="0" maxOccurs="unbounded"/>
<xs:choice>
<xs:sequence minOccurs="0">
<xs:element ref="RootContent1" minOccurs="0"/>
<xs:element ref="RootContent2" minOccurs="0"/>
</xs:sequence>
<xs:sequence minOccurs="0">
<xs:element ref="RootContent2" minOccurs="0"/>
<xs:element ref="RootContent1" minOccurs="0"/>
</xs:sequence>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="RootContent2" type="xs:string"/>
<xs:element name="RootContent1" type="xs:string"/>
Upvotes: 2