Complex data types

Complex type elements fall down into the following categories:

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:

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>