Simple-Type Elements
- To use XML Schema's built-in simple types.
- To derive your own types.
- To define list types.
- To define union types.
- To declare global simple-type elements.
- To set default and fixed values.
- To allow for nil values.
Overview
Simple-type elements have no children or attributes. For example, the Name element below is a simple-type element; whereas the Person and HomePage elements are not.
Code Sample: SimpleTypes/Demos/SimpleType.xml
<?xml version="1.0"?> <Person> <Name>Mark Twain</Name> <HomePage URL="http://www.marktwain.com"/> </Person>
As the diagram below shows, a simple type can either be built-in or user-derived. In this lesson, we will examine both.
![]()
Built-in Simple Types
XML Schema specifies 44 built-in types, 19 of which are primitive.
19 Primitive Data Types
The 19 built-in primitive types are listed below.
- string
- boolean
- decimal
- float
- double
- duration
- dateTime
- time
- date
- gYearMonth
- gYear
- gMonthDay
- gDay
- gMonth
- hexBinary
- base64Binary
- anyURI
- QName
- NOTATION
Built-in Derived Data Types
The other 25 built-in data types are derived from one of the primitive types listed above.
- normalizedString
- token
- language
- NMTOKEN
- NMTOKENS
- Name
- NCName
- ID
- IDREF
- IDREFS
- ENTITY
- ENTITIES
- integer
- nonPositiveInteger
- negativeInteger
- long
- int
- short
- byte
- nonNegativeInteger
- unsignedLong
- unsignedInt
- unsignedShort
- unsignedByte
- positiveInteger
Defining a Simple-type Element
A simple-type element is defined using the type attribute.
Code Sample: SimpleTypes/Demos/Author.xsd
<?xml version="1.0" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Author">
<xs:complexType>
<xs:sequence>
<xs:element name="FirstName" type="xs:string"/>
<xs:element name="LastName" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Notice the FirstName and LastName elements in the code sample below. They are not explicitly defined as simple type elements. Instead, the type is defined with the type attribute. Because the value (string in both cases) is a simple type, the elements themselves are simple-type elements.
The Author element is a complex-type element. Complex-type elements will be covered in "Complex-Type Elements".
User-derived Simple Types
A schema author can derive a new simple type using the <xs:simpleType> element. This simple type can then be used in the same way that built-in simple types are.
Simple types are derived by restricting built-in simple types or other user-derived simple types. For example, you might want to create a simple type called password that is an eight-character string. To do so, you would start with the xs:string type and restrict its length to eight characters. This is done nesting the <xs:restriction> element inside of the <xs:simpleType> element.
Code Sample: SimpleTypes/Demos/Password.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="Password">
<xs:restriction base="xs:string">
<xs:length value="8"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="User">
<xs:complexType>
<xs:sequence>
<xs:element name="PW" type="Password"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Code Sample: SimpleTypes/Demos/Password.xml
<?xml version="1.0"?> <User xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Password.xsd"> <PW>MyPasWrd</PW> </User>
Applying Facets
Simple types can be derived by applying one or more of the following facets.
- length
- minLength
- maxLength
- pattern
- enumeration
- whiteSpace
- minInclusive
- minExclusive
- maxInclusive
- maxExclusive
- totalDigits
- fractionDigits
Controlling Length
The length of a string can be controlled with the length, minLength, and maxLength facets. We used the length facet in the example above to create a Password simple type as an eight-character string. We could use minLength and maxLength to allow passwords that were between six and twelve characters in length.
The schema below shows how this is done. The two XML instances shown below it are both valid, because the length of the password is between six and twelve characters.
Code Sample: SimpleTypes/Demos/Password2.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="Password">
<xs:restriction base="xs:string">
<xs:minLength value="6"/>
<xs:maxLength value="12"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="User">
<xs:complexType>
<xs:sequence>
<xs:element name="PW" type="Password"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Code Sample: SimpleTypes/Demos/Password2.xml
<?xml version="1.0"?> <User xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Password2.xsd"> <PW>MyPass</PW> </User>
Code Sample: SimpleTypes/Demos/Password2b.xml
<?xml version="1.0"?> <User xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Password2.xsd"> <PW>MyPassWord</PW> </User>
Specifying Patterns
Patterns are specified using the xs:pattern element and regular expressions. For example, you could use the xs:pattern element to restrict the Password simple type to consist of between six and twelve characters, which can only be lowercase and uppercase letters and underscores.
Code Sample: SimpleTypes/Demos/Password3.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="Password">
<xs:restriction base="xs:string">
<xs:pattern value="[A-Za-z_]{6,12}"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="User">
<xs:complexType>
<xs:sequence>
<xs:element name="PW" type="Password"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Code Sample: SimpleTypes/Demos/Password3.xml
<?xml version="1.0"?> <User xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Password3.xsd"> <PW>MyPassword</PW> </User>
Working with Numbers
Numeric simple types can be derived by limiting the value to a certain range using minExclusive, minInclusive, maxExclusive, and maxInclusive. You can also limit the total number of digits and the number of digits after the decimal point using totalDigits and fractionDigits, respectively.
Mins and Maxs
The following example shows how to derive a simple type called Salary, which is a decimal between 10,000 and 90,000.
Code Sample: SimpleTypes/Demos/Employee.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="Salary">
<xs:restriction base="xs:decimal">
<xs:minInclusive value="10000"/>
<xs:maxInclusive value="90000"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="Employee">
<xs:complexType>
<xs:sequence>
<xs:element name="Salary" type="Salary"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Code Sample: SimpleTypes/Demos/JohnSmith.xml
<?xml version="1.0"?> <Employee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Employee.xsd"> <Salary>55000</Salary> </Employee>
Number of Digits
Using totalDigits and fractionDigits, we can further specify that the Salary type should consist of seven digits, two of which come after the decimal point. Both totalDigits and fractionDigits are maximums. That is, if totalDigits is specified as 5 and fractionDigits is specified as 2, a valid number could have no more than five digits total and no more than two digits after the decimal point.
Code Sample: SimpleTypes/Demos/Employee2.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="Salary">
<xs:restriction base="xs:decimal">
<xs:minInclusive value="10000"/>
<xs:maxInclusive value="90000"/>
<xs:fractionDigits value="2"/>
<xs:totalDigits value="7"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="Employee">
<xs:complexType>
<xs:sequence>
<xs:element name="Salary" type="Salary"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Code Sample: SimpleTypes/Demos/MarySmith.xml
<?xml version="1.0"?> <Employee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Employee2.xsd"> <Salary>55000.00</Salary> </Employee>
Enumerations
A derived type can be a list of possible values. For example, the JobTitle element could be a list of pre-defined job titles.
Code Sample: SimpleTypes/Demos/Employee3.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="Salary">
<xs:restriction base="xs:decimal">
<xs:minInclusive value="10000"/>
<xs:maxInclusive value="90000"/>
<xs:fractionDigits value="2"/>
<xs:totalDigits value="7"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="JobTitle">
<xs:restriction base="xs:string">
<xs:enumeration value="Sales Manager"/>
<xs:enumeration value="Salesperson"/>
<xs:enumeration value="Receptionist"/>
<xs:enumeration value="Developer"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="Employee">
<xs:complexType>
<xs:sequence>
<xs:element name="Salary" type="Salary"/>
<xs:element name="Title" type="JobTitle"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Code Sample: SimpleTypes/Demos/SteveSmith.xml
<?xml version="1.0"?> <Employee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Employee3.xsd"> <Salary>90000.00</Salary> <Title>Sales Manager</Title> </Employee>
Whitespace-handling
By default, whitespace in elements of the datatype xs:string is preserved in XML documents; however, this can be changed for datatypes derived from xs:string. This is done with the xs:whiteSpace element, the value of which must be one of the following.
- preserve - whitespace is not normalized. That is to say, it is kept as is.
- replace - all tabs, line feeds, and carriage returns are replaced by single spaces.
- collapse - all tabs, line feeds, and carriage returns are replaced by single spaces and then all groups of single spaces are replaced with one single space. All leading and trailing spaces are then removed (i.e, trimmed).
In SimpleTypes/Demos/Password.xsd, we looked at restricting the length of a Password datatype to eight characters using the xs:length element. If whitespace is preserved, then leading and trailing spaces are considered part of the password. In the following example, we set xs:whiteSpace to collapse, thereby discounting any leading or trailing whitespace. As you can see, this allows the XML instance author to format the document without consideration of whitespace.
Code Sample: SimpleTypes/Demos/Password4.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="Password">
<xs:restriction base="xs:string">
<xs:length value="8"/>
<xs:whiteSpace value="collapse"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="User">
<xs:complexType>
<xs:sequence>
<xs:element name="PW" type="Password"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Code Sample: SimpleTypes/Demos/Password4.xml
<?xml version="1.0"?> <User xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Password4.xsd"> <PW> 12345678 </PW> </User>
Specifying Element Type Locally
So far in this lesson, we have been defining simple types globally and then setting the type attribute of element declarations to be of our derived simple types. This makes it easy to reuse a simple type across multiple elements, as we saw with the ProperName type in the last exercise.
It is also possible to define the type of an element locally. The type is then unnamed and applicable only to that element. The only reason to do this is to clearly show that the type is specific to that element and not meant for reuse.
Code Sample: SimpleTypes/Demos/PasswordLocal.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="User">
<xs:complexType>
<xs:sequence>
<xs:element name="PW">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:length value="8"/>
<xs:whiteSpace value="collapse"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Nonatomic Types
All of XML Schema's built-in types are atomic, meaning that they cannot be broken down into meaningful bits. XML Schema provides for two nonatomic types: lists and unions.
Lists
List types are sequences of atomic types separated by whitespace; you can have a list of integers or a list of dates. Lists should not be confused with enumerations. Enumerations provide optional values for an element. Lists represent a single value within an element.
Code Sample: SimpleTypes/Demos/EmployeeList.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="Salary">
<xs:restriction base="xs:decimal">
<xs:minInclusive value="10000"/>
<xs:maxInclusive value="90000"/>
<xs:fractionDigits value="2"/>
<xs:totalDigits value="7"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="JobTitle">
<xs:restriction base="xs:string">
<xs:enumeration value="Sales Manager"/>
<xs:enumeration value="Salesperson"/>
<xs:enumeration value="Receptionist"/>
<xs:enumeration value="Developer"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="DateList">
<xs:list itemType="xs:date"/>
</xs:simpleType>
<xs:element name="Employee">
<xs:complexType>
<xs:sequence>
<xs:element name="Salary" type="Salary"/>
<xs:element name="Title" type="JobTitle"/>
<xs:element name="VacationDays" type="DateList"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Code Sample: SimpleTypes/Demos/SandySmith.xml
<?xml version="1.0"?> <Employee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="EmployeeList.xsd"> <Salary>44000</Salary> <Title>Salesperson</Title> <VacationDays>2006-8-13 2006-08-14 2006-08-15</VacationDays> </Employee>
Unions
Union types are groupings of types, essentially allowing for the value of an element to be of more than one type. In the example below, two atomic simple types are derived: RunningRace and Gymnastics. A third simple type, Event, is then derived as a union of the previous two. The Event element is of the Event type, which means that it can either be of the RunningRace or the Gymnastics type.
Code Sample: SimpleTypes/Demos/Program.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="RunningRace">
<xs:restriction base="xs:string">
<xs:enumeration value="100 meters"/>
<xs:enumeration value="10 kilometers"/>
<xs:enumeration value="440 yards"/>
<xs:enumeration value="10 miles"/>
<xs:enumeration value="Marathon"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Gymnastics">
<xs:restriction base="xs:string">
<xs:enumeration value="Vault"/>
<xs:enumeration value="Floor"/>
<xs:enumeration value="Rings"/>
<xs:enumeration value="Beam"/>
<xs:enumeration value="Uneven Bars"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Event">
<xs:union memberTypes="RunningRace Gymnastics"/>
</xs:simpleType>
<xs:element name="Program">
<xs:complexType>
<xs:sequence>
<xs:element name="Event" type="Event"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Code Sample: SimpleTypes/Demos/100Meters.xml
<?xml version="1.0"?> <Program xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Program.xsd"> <Event>100 meters</Event> </Program>
Declaring Global Simple-Type Elements
When an element declaration is a child of the xs:schema element, the declared element is global. Global elements can be referenced by other element declarations, allowing for element reuse. Take a look at the following example.
Code Sample: SimpleTypes/Demos/AuthorGlobal.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="FirstName" type="xs:string"/>
<xs:element name="LastName" type="xs:string"/>
<xs:element name="Author">
<xs:complexType>
<xs:sequence>
<xs:element ref="FirstName"/>
<xs:element ref="LastName"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
In this example, the FirstName and LastName elements are both declared globally. The global elements are then referenced as children of the Author sequence.
Global vs. Local Simple-Type Elements
The major advantage of declaring an element globally is that the element can then be referenced throughout the schema. This makes the code more modular and easier to maintain. For example, suppose that the song schema contained MusicWriter, LyricsWriter, and Singer elements. Each of these elements might have the child element Name. If the Name element is declared globally, any changes to that element can be made in one location.
The major disadvantage of declaring elements globally is that all global elements must have unique names.
Code Sample: SimpleTypes/Demos/BookLocal.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="PersonTitle">
<xs:restriction base="xs:string">
<xs:enumeration value="Mr."/>
<xs:enumeration value="Ms."/>
<xs:enumeration value="Dr."/>
</xs:restriction>
</xs:simpleType>
<xs:element name="Book">
<xs:complexType>
<xs:sequence>
<xs:element name="Title" type="xs:string"/>
<xs:element name="Author">
<xs:complexType>
<xs:sequence>
<xs:element name="Title" type="PersonTitle"/>
<xs:element name="Name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Notice that there are two elements named Title, which can appear in different locations in the XML instance and are of different types. When the Title element appears at the root of the XML instance, its value can be any string; whereas, when it appears as a child of Author, its value is limited to "Mr.", "Ms.", or "Dr."
The example below defines a similar content model; however, because the elements are declared globally, the name Title cannot be used twice.
Code Sample: SimpleTypes/Demos/BookGlobal.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="PersonTitle">
<xs:restriction base="xs:string">
<xs:enumeration value="Mr."/>
<xs:enumeration value="Ms."/>
<xs:enumeration value="Dr."/>
</xs:restriction>
</xs:simpleType>
<xs:element name="BookTitle" type="xs:string"/>
<xs:element name="Title" type="PersonTitle"/>
<xs:element name="Name" type="xs:string"/>
<xs:element name="Book">
<xs:complexType>
<xs:sequence>
<xs:element ref="BookTitle"/>
<xs:element name="Author">
<xs:complexType>
<xs:sequence>
<xs:element ref="Title"/>
<xs:element ref="Name"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Default Values
Elements that do not have any children can have default values. To specify a default value, use the default attribute of the xs:element element.
Code Sample: SimpleTypes/Demos/EmployeeDefault.xsd
<?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">---- Code Omitted ----<xs:element name="Employee"> <xs:complexType> <xs:sequence> <xs:element name="Salary" type="Salary"/> <xs:element name="Title" type="JobTitle" default="Salesperson"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
When defaults are set in the XML schema, the following rules apply for the instance document.
- If the element appears in the document with content, the default value is ignored.
- If the element appears without content, the default value is applied.
- If the element does not appear, the element is left out. In other words, providing a default value does not imply that the element should be inserted if the XML instance author leaves it out.
Examine the following XML instance. The Title element cannot be empty; it requires one of the values from the enumeration defined in the JobTitle simple type. However, in accordance with number 2 above, the schema processor applies the default value of Salesperson to the Title element, so the instance validates successfully.
Code Sample: SimpleTypes/Demos/MikeSmith.xml
<?xml version="1.0"?> <Employee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="EmployeeDefault.xsd"> <Salary>90000</Salary> <Title/> </Employee>
Fixed Values
Element values can be fixed, meaning that, if they appear in the instance document, they must contain a specified value. Fixed elements are often used for boolean switches.
Code Sample: SimpleTypes/Demos/EmployeeFixed.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="Salary">
<xs:restriction base="xs:decimal">
<xs:minInclusive value="10000"/>
<xs:maxInclusive value="90000"/>
<xs:fractionDigits value="2"/>
<xs:totalDigits value="7"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="JobTitle">
<xs:restriction base="xs:string">
<xs:enumeration value="Sales Manager"/>
<xs:enumeration value="Salesperson"/>
<xs:enumeration value="Receptionist"/>
<xs:enumeration value="Developer"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="Employee">
<xs:complexType>
<xs:sequence>
<xs:element name="Salary" type="Salary"/>
<xs:element name="Title" type="JobTitle"/>
<xs:element name="Status" type="xs:string" fixed="current"
minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
The MinOccurs attribute is used to make the Status element optional. However, if it is used, it must contain the value current or be left empty, in which case, the value current is implied. The file SimpleTypes/Demos/LauraSmith.xml in the Demos folder validates against this schema.
Nil Values
When an optional element is left out of an XML instance, it has no clear meaning. For example, suppose a schema declares a Name element as having required FirstName and LastName elements and an optional MiddleName element. And suppose a particular instance of this schema does not include the MiddleName element. Does this mean that the instance author did not know the middle name of the person in question or does it mean the person in question has no middle name?
Setting the nillable attribute of xs:element to true indicates that such elements can be set to nil by setting the xsi:nil attribute to true.
Code Sample: SimpleTypes/Demos/AuthorNillable.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Author">
<xs:complexType>
<xs:sequence>
<xs:element name="FirstName" type="xs:string"/>
<xs:element name="MiddleName" type="xs:string" nillable="true"/>
<xs:element name="LastName" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Code Sample: SimpleTypes/Demos/MarkTwain.xml
<?xml version="1.0"?> <Author xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="AuthorNillable.xsd"> <FirstName>Mark</FirstName> <MiddleName xsi:nil="true"/> <LastName>Twain</LastName> </Author>
By including the MiddleName element and setting xsi:nil to true, we are explicitly stating that Mark Twain has no middle name.
Simple-Type Elements Conclusion
In this lesson of the XML Schema tutorial, you have learned to work with XML Schema's built-in simple types, to derive your own simple types, and to declare simple-type elements. We will now take a look at complex-type elements.
