XML Schema Complex Elements and Data Types
Define XML Schema complex elements and data types with XSD through focused document structure examples.
How do we define complex elements in XML Schema?
<book>
<title>Yunus Emre Divani</title>
<language>Turkish</language>
</book>
There are two common ways to define complex elements.
<xs:element name="book">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="language" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
In the first method, we define the complex type directly inside the element.
If the structure is unique to that element and will not be reused elsewhere, this approach is fine.
If the same structure will be used by multiple elements, I recommend the second method:
<xs:element name="book" type="bookEntry"/>
<xs:element name="aboutBook" type="bookEntry"/>
<!-- You can define for one or more elements. -->
<xs:complexType name="bookEntry">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="language" type="xs:string"/>
</xs:sequence>
</xs:complexType>
You can also extend a complex type with the properties of another type. From this point on, I will generally use the second method in the examples.
<xs:element name="book" type="bookEntry"/>
<xs:element name="aboutBook" type="aboutBook"/>
<!-- You can define for one or more elements. -->
<xs:complexType name="bookEntry">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="language" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="aboutBook">
<xs:complexContent>
<xs:extension base="bookEntry">
<xs:sequence>
<xs:element name="author" type="xs:string"/>
<xs:element name="isbn" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>Empty Elements
<book isbn="9759954949"/>
To define this as a complex element:
<xs:element name="book" type="bookEntry"/>
<xs:complexType name="bookEntry">
<xs:attribute name="isbn" type="xs:positiveInteger"/>
</xs:complexType>
This defines an empty book element with only an isbn attribute.
Element Only
<book>
<title>Yunus Emre Divani</title>
<language>Turkish</language>
</book>
For this XML example, the complex type definition looks like this:
<xs:element name="book" type="bookStructure"/>
<xs:complexType name="bookStructure">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="language" type="xs:string"/>
</xs:sequence>
</xs:complexType>Text Content Only
<book isbn="9759954949">Yunus Emre Divani</book>
To define a book element that contains text and also has an attribute:
<xs:element name="book" type="bookStructure"/>
<xs:complexType name="bookStructure">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="isbn" type="xs:positiveInteger" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>Mixed Content
<book>
Book Title: <title>Yunus Emre Divani</title>
Language: <language>Turkish</language>
ISBN: <isbn>9759954949</isbn>
</book>
For elements with mixed content, define the complex type as follows:
<xs:element name="book" type="bookStructure"/>
<xs:complexType mixed="true" name="bookStructure">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="language" type="xs:string"/>
<xs:element name="isbn" type="xs:positiveInteger"/>
</xs:sequence>
</xs:complexType>Indicators
<all> allows child elements to appear in any order. Each child can appear at most once unless occurrence rules are defined.
<xs:complexType mixed="true" name="bookStructure">
<xs:all>
<xs:element name="title" type="xs:string"/>
<xs:element name="language" type="xs:string"/>
<xs:element name="isbn" type="xs:positiveInteger"/>
</xs:all>
</xs:complexType>
<choice> allows one of the listed child elements to be used.
<xs:complexType mixed="true" name="bookStructure">
<xs:choice>
<xs:element name="title" type="xs:string"/>
<xs:element name="language" type="xs:string"/>
<xs:element name="isbn" type="xs:positiveInteger"/>
</xs:choice>
</xs:complexType>
<sequence> requires child elements to appear in the specified order.
<xs:complexType mixed="true" name="bookStructure">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="language" type="xs:string"/>
<xs:element name="isbn" type="xs:positiveInteger"/>
</xs:sequence>
</xs:complexType>
<maxOccurs> determines the maximum number of times a child element can appear.
<minOccurs> determines the minimum number of times a child element must appear.
<xs:complexType mixed="true" name="bookStructure">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="language" type="xs:string" maxOccurs="10" minOccurs="1"/>
</xs:sequence>
</xs:complexType>
In the example above, the language element must appear at least once and can appear at most 10 times.
With <group>, you can create a reusable group and use it in multiple elements. You can also use the indicators above inside a group.
<xs:group name="bookGroup">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="language" type="xs:string"/>
</xs:sequence>
</xs:group>
<xs:element name="book" type="bookEntry"/>
<xs:complexType name="bookEntry">
<xs:sequence>
<xs:group ref="bookGroup"/>
<xs:element name="isbn" type="xs:positiveInteger"/>
</xs:sequence>
</xs:complexType>
The same idea applies to <attributeGroup>:
<xs:attributeGroup name="bookAttribute">
<xs:attribute name="isbn" type="xs:positiveInteger"/>
</xs:attributeGroup>
<xs:element name="book" type="bookEntry"/>
<xs:complexType name="bookEntry">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="language" type="xs:string"/>
</xs:sequence>
<xs:attributeGroup ref="bookAttribute"/>
</xs:complexType>
<any> is used to allow extension elements. In the example below, another element can be added after the defined fields.
<xs:complexType name="bookStructure">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="language" type="xs:string"/>
<xs:any minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<anyAttribute> is used to allow additional attributes.
<xs:complexType name="bookStructure">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="language" type="xs:string"/>
</xs:sequence>
<xs:anyAttribute/>
</xs:complexType>
substitutionGroup lets one element substitute for another element.
<xs:element name="book" type="xs:string"/>
<xs:element name="title" substitutionGroup="book"/>
<!-- When defining XML -->
<book>Yunus Emre Divani</book>
<!-- or -->
<title>Yunus Emre Divani</title>
This lets us use either element in the XML. If we add block="substitution" as an attribute, the <title></title> form shown above is no longer allowed.
Data Types
Now let's look at XML Schema data types.
Text Data Types
| Data Type | Description |
|---|---|
| ENTITIES | A list of entity references |
| ENTITY | An entity reference |
| ID | A unique ID value assigned to an element |
| IDREF | A reference to another element's ID |
| IDREFS | A list of ID references |
| language | A valid language identifier |
| Name | A valid XML name |
| NCName | An XML name without a namespace prefix |
| NMTOKEN | A valid XML name token |
| NMTOKENS | A list of XML name tokens |
| normalizedString | Text with normalized line breaks and tabs |
| QName | A qualified XML name |
| string | Text |
| token | Text with collapsed whitespace |
Date Data Types
| Data Type | Description |
|---|---|
| date | Date data |
| dateTime | Date and time data |
| duration | Interval data |
| gDay | Day (DD) |
| gMonth | Month (MM) |
| gMonthDay | Month - Day (MM-DD) |
| gYear | Year (YYYY) |
| gYearMonth | Year - Month (YYYY-MM) |
| time | Time |
Numeric Data Types
| Data Type | Description |
|---|---|
| byte | signed 8-bit integer |
| decimal | decimal value |
| int | signed 32-bit integer |
| integer | integer value |
| long | signed 64-bit integer |
| negativeInteger | Negative values (..,-2,-1) |
| nonNegativeInteger | Non-negative values (0,1,2,..) |
| nonPositiveInteger | Non-positive values (..,-2,-1,0) |
| positiveInteger | Positive values (1,2,..) |
| short | signed 16-bit integer |
| unsignedLong | unsigned 64-bit integer |
| unsignedInt | unsigned 32-bit integer |
| unsignedShort | unsigned 16-bit integer |
| unsignedByte | unsigned 8-bit integer |
Miscellaneous Data Types
| Data Type | Description |
|---|---|
| anyURI | URI value |
| base64Binary | Base64-encoded binary data |
| boolean | True or false value |
| double | Double-precision floating-point number |
| float | Floating-point number |
| hexBinary | Hexadecimal binary data |
| NOTATION | Notation declared in the schema |
| QName | Qualified XML name |