Reputation: 503
I have base class for all child elements in my XSD
<xs:complexType name="BaseItem">
<xs:attribute name="id" type="string" use="required"/>
</xs:complexType>
And extenders of this element
<xs:complexType name="Package">
<xs:complexContent>
<xs:extension base="BaseItem">
<xs:sequence>
<xs:element name="SubElement" type="SubElementType"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Class">
<xs:complexContent>
<xs:extension base="BaseItem">
<xs:sequence>
<xs:element name="SubElement2" type="SubElementType2"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
.......
etc....
And xml examples for this XSD:
XML1:
<Root><Package id="xxx"><SubElement/></Package></Root>
XML2:
<Root><Class id="xxx"><SubElement2/></Class></Root>
XML3:
<Root><Method id="xxx"><SubElement3/></Method></Root>
XML4:
<Root><Method id="xxx"><SubElement3/></Method></Root>
How I can specify root element in this XSD without defining all possible children?
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
//?????
</xs:sequence>
</xs:complexType>
</xs:element>
Is any way to specify children through base type? Smth:
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<element type="BaseItem"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Or without specifying name of element this is impossible?
Upvotes: 1
Views: 1885
Reputation: 3428
You could use substitution group (http://www.w3schools.com/schema/schema_complex_subst.asp) in this way
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:complexType name="base_item_type">
<xs:attribute name="id" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="package_type">
<xs:complexContent>
<xs:extension base="base_item_type">
<xs:sequence>
<xs:element name="SubElement" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="class_type">
<xs:complexContent>
<xs:extension base="base_item_type">
<xs:sequence>
<xs:element name="SubElement2" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!-- abstract attribute to prevent occurence of BaseElement-->
<xs:element name="BaseElement" type="base_item_type" abstract="true"/>
<!-- Package and Class element might be used instead of BaseElement-->
<!-- But they also can be put as root element -->
<xs:element name="Package" type="package_type" substitutionGroup="BaseElement" />
<xs:element name="Class" type="class_type" substitutionGroup="BaseElement"/>
<!-- Root element -->
<xs:element name="RootElement">
<xs:complexType>
<xs:sequence>
<xs:element ref="BaseElement" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
But I'm not sure if it is better than choice in the root element - just because in this way also "package" and "class" can be put as a root element directly. Personally I would prefer one root element with (although bigger) choice.
Upvotes: 2