Complex data types
Complex type elements fall down into the following categories:
- empty elements containing only attributes
- elements containing text only and attributes, but no child elements
- elements containing child elements, but no attributes
- elements containing both child elements and attributes
A general structure of a complex type declaration is as follows:
<xs:element name="name">
<xs:complexType>
declarations
</xs:complexType>
</xs:element>
Empty elements and attributes
The syntax is as follows:
<xs:element name="name">
<xs:complexType>
attributes
</xs:complexType>
</xs:element>
- Example:
- The following XML element:
<person name="Joe Doe" age="50" />
has two attributes which can be declared as follows:
<xs:element name="person">
<xs:complexType>
<xs:attribute name="name" type="xs:string" />
<xs:attribute name="age" type="xs:string" />
</xs:complexType>
</xs:element>
Elements with attributes but no child elements
If the element is not empty and contains attributes and no child elements,
the syntax is as follows:
<xs:element name="name">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="type">
attributes
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
Extension is a tool for creating complex custom data types.
- Example:
- The following XML element:
<person gender="male" age="50">Joe Doe</person>
has two attributes which can be declared as follows:
<xs:element name="person">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="gender" type="xs:string"
/>
<xs:attribute name="age" type="xs:string"
/>
</xs:simpleContent>
</xs:complexType>
</xs:element>
Cross-referencing elements and attributes
Rather than nesting the attribute declarations within an element, one can
create references to them by following the general syntax:
<xs:element ref="elementReference">
<xs:attribute ref="attributeReference">
Thus, the above example can be rewritten as follows:
- Example:
- The following XML element:
<person gender="male" age="50">Joe Doe</person>
has two attributes which can be declared as follows:
<xs:attribute name="gender" type="xs:string" />
<xs:attribute name="age" type="xs:string" />
<xs:element name="person">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute ref="gender" use="required"
/>
<xs:attribute ref="age" use="required"
/>
</xs:simpleContent>
</xs:complexType>
</xs:element>
Elements with child elements but no attributes
For such elements we use the compositor
<xs:element name="name">
<xs:complexType>
<xs:compositor>
elements
</xs:compositor>
</xs:complexType>
</xs:element>
XML schema supports the following compositors:
- sequence - defines an order for the child elements
- choice - allows only ONE element from the list to appear as a
child element
- all - allow any of the child elements to appear with no restriction
on the order and occurrence.
- Example:
-
<element name="address">
<xs:complexType>
<xs:sequence>
<xs:element name="street" style="xs:string" />
<xs:element name="city" style="xs:string" />
<xs:element name="state" style="xs:string" />
<xs:element name="country" style="xs:string" />
</xs:sequence>
</xs:complexType>
<element>
- Example:
-
<element name="sponsor">
<xs:complexType>
<xs:choice>
<xs:element name="parent" style="xs:string" />
<xs:element name="guardian" style="xs:string" />
</xs:choice>
</xs:complexType>
<element>
- Example:
-
<element name="parents">
<xs:complexType>
<xs:all>
<xs:element name="father" style="xs:string" />
<xs:element name="mother" style="xs:string" />
</xs:all>
</xs:complexType>
<element>
Compositors can be nested and combined with each other:
- Example:
-
<element name="account">
<xs:complexType>
<xs:sequence>
<xs:choice>
<xs:element name="person" style="xs:string"
/>
<xs:element name="company" style="xs:string"
/>
</xs:choice>
<xs:choice>
<xs:element name="checking" style="xs:string"
/>
<xs:element name="savings" style="xs:string"
/>
</xs:choice>
</xs:sequence>
</xs:complexType>
<element>
Specifying the item occurrence
This can be done by using the attributed minOccurs and
maxOccurs (case sensitive!).
<xs:element name="parent" type="xs:string" minOccurs="1" maxOccurs="2"
/>
The maxOccurs attribute, if present, can take on any positive
value or the value "unbounded". If some of those attributes are
missing, their default values are set up as follows:
| Situation | minOccurs |
maxOccurs |
| only minOccurs is missing |
0 | maxOccurs |
| only maxOccurs is missing |
minOccurs | minOccurs |
| both are missing |
1 | 1 |
Elements with child elements and attributes
The general syntax is as follows:
<xs:element name="name">
<xs:complexType>
<xs:compositor>
elements
</xs:compositor>
</xs:complexType>
attributes
</xs:element>
In the below example the element and attributed declarations can be used
instead of the references. Note that comment as it is defined, is
an optional child element.
- Example:
-
<element name="patient">
<xs:complexType>
<xs:sequence>
<xs:element ref="lastName" />
<xs:element ref="firstName" />
<xs:element ref="id" />
<xs:element ref="comment" minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute ref="age" />
<xs:attribute ref="gender" />
</xs:complexType>
<element>
Mixed content
The attribute mixed="true" of element complexType
specifies the element containing both text and child elements. The structure
of the child elements can be specified by the methods described above.
- Example:
- The XML content
<summary>
Patient <name>Joe Doe</name> was taken by
<personnel>Mary Brown</personnel> on 8/3/2005.
</summary>
can be declared as follows:
<element name="summary">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element ref="name" />
<xs:element ref="personnel" />
</xs:sequence>
</xs:complexType>
<element>