XML Schema
CONTENTS
Schema Documents
The root element
Schema document contents
Comments
Reference from instance document
Documents with no namespace
Documents with a namespace
Documents with multiple namespaces
Include, Redefine, Import
Basic element declarations
Any content
Empty element
Simple content
Simple content with a default
Simple content with a fixed value
Enumerated values
Empty element with attributes
Element with attributes and arbitrary content
Optional, required and prohibited attributes
Default attributes
Fixed attributes
Enumerated values for attributes
Document Structure
Sequences of child elements
Optional and repeatable child elements
Alternative elements
Nested sequence and choice constructions
Unordered sequences
The any element
Restricting the namespace for any
Any attribute
Namespaces for anyAttribute
Groups
Elements with constrained attributes and unconstrained content
Elements with constrained attributes and constrained content
Local element declarations
Global attribute declarations
Attribute groups
Big Example
Unique and Key
Data Types
Primitive types
Built-in numeric types
Built-in string types
Nils
Defining simple types
Facets
length
minLength, maxLength
pattern
enumeration
whiteSpace
minInclusive, minExclusive, maxInclusive, maxExclusive
totalDigits, fractionDigits
Lists
Unions
Complex Types
Derived Complex Types
Complex Types derived from Simple Types

Schema Documents

The root element

Root element is called 'schema'.
Optional version attribute, but that's application defined.
Namespace is http://www.w3.org/2001/XMLSchema.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> ... </xs:schema>
If the instance document uses a namespace, it is called the target namespace. The namespace iteself must be declared, and then identified as the target namespace by using the 'targetNamespace' attribute.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:pk="http://www.ouch.com/namespaces/pooka" targetNamespace="http://www.ouch.com/namespaces/pooka"> ... </xs:schema>

Schema document contents

Top-level schema management elements:
  • import
  • include
  • redefine
Top-level model definition elements:
  • notation
  • simpleType
  • complexType
  • attribute
  • attributeGroup
  • group
  • element

Comments

Can use ordinary XML comments, but more appropriate to use annotation elements.
Annotation element can also occur at toplevel.
Annotation includes <documentation> element as child, intended for human consumption
Annotation includes <appinfo> element as child, intended for machine consumption
<xs:annotation> <xs:documentation>For humans</xs:documentation> <xs:appinfo>For machines</xs:appinfo> </xs:annotation>
to top

Reference from instance document

Complicated by namespace considerations!

Documents with no namespace

The document and the schema do not define any namesapce.
<a xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="path-to-doc.xsd"> ... </a>

Documents with a namespace

The document uses the http://www.ouch.com/namespaces/root namespace as the default namespace. This namespace must be the target namespace of the schema.
<a xmlns="http://www.ouch.com/namespaces/root" xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://www.ouch.com/namespaces/root root-schema.xsd"> ... </a>

Documents with multiple namespaces

The document uses the http://www.ouch.com/namespaces/root and http://www.ouch.com/namespaces/branch namespaces, both of which have schemas.
<a xmlns:root="http://www.ouch.com/namespaces/root" xmlns:branch="http://www.ouch.com/namespaces/branch" xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://www.ouch.com/namespaces/root root-schema.xsd http://www.ouch.com/namespaces/branch branch-schema.xsd"> ... </a>
to top

Include, Redefine, Import

A schema can be implemented as a collection of documents.
There is typically a master document, which includes or redefines subsidiary document.
Import is used to bring in declarations from a different schema.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:cc="http://www.ouch.com/namespaces/concepts" targetNamespace="http://www.ouch.com/namespaces/concepts"> <xs:include schemaLocation="qualities-schema.xsd"/> <xs:redefine schemaLocation="properties-schema.xsd"/> <xs:import schemaLocation="definitions-schema.xsd"/> </xs:schema>
When including and redefining, the secondary schema should not have a target namespace, as the declarations in the secondary schema are assigned to the parent document's target namespace. Apart from that distinction, include and redefine can be thought of as textual inclusion.
Redefine is used when the secondary document overrides declarations in the parent document. The rules are a bit complex.
The imported schema is used to verify values in namespaces other than the target namespace of the parent document.
to top

Basic element declarations

Any content

<xs:element name="a"/>

Empty element

<xs:element name="a"><complexType/></element>

Simple content

<xs:element name="a" type="xs:string"/>

Simple content with a default

<xs:element name="a" type="xs:integer" default="10"/>
Value is inserted when element is present but empty.
For string types, this could be ambiguous! - use xsi:nil="true" to avoid having the default value being inserted

Simple content with a fixed value

<xs:element name="a" type="xs:integer" fixed="0"/>
Value is inserted when element is present but empty.
Error if there is a value different from the declared one.

Enumerated values

<xs:element name="a"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="x"/> <xs:enumeration value="y"/> <xs:enumeration value="z"/> </xs:restriction> </xs:simpleType> </xs:element>

Empty element with attributes

<xs:element name="a"> <xs:complexType> <xs:attribute name="x" type="xs:integer"/> <xs:attribute name="y" type="xs:integer"/> </xs:complexType> </xs:element>
Since no sub-elements are declared, they are forbidden.

Element with attributes and arbitrary content

<xs:element name="a"> <xs:complexType mixed="true"> <xs:attribute name="x" type="xs:string"/> <xs:attribute name="y" type="xs:string"/> </xs:complexType> </xs:element>
Cannot constrain the content with this approach.
Use the following, if the elements needed to be specified as well.
<xs:element name="a"> <xs:complexType mixed="true"> <xs:simpleContent> <xs:extension base="string"> <xs:attribute name="x" type="xs:string"/> <xs:attribute name="y" type="xs:string"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element>

Optional, required and prohibited attributes

The 'use' attribute can be set to 'optional', 'required', or 'prohibited'.
Attributes are optional by default
<xs:element name="a"> <xs:complexType mixed="true"> <xs:attribute name="x" type="xs:string" use="optional"/> <xs:attribute name="y" type="xs:string" use="required"/> <xs:attribute name="z" type="xs:string" use="prohibited"/> </xs:complexType> </xs:element>

Default attributes

<xs:element name="a"> <xs:complexType mixed="true"> <xs:attribute name="x" type="xs:string" default="rstu"/> </xs:complexType> </xs:element>
The default is applied if the attribute is missing, and not if it's present but empty.
Cannot specify a default when the use is required.

Fixed attributes

<xs:element name="a"> <xs:complexType mixed="true"> <xs:attribute name="x" type="xs:string" fixed="stuv"/> </xs:complexType> </xs:element>
The fixed is inserted if the attribute is missing.
Error if the attribute is present and not equal to the fixed value.
An attribute can be fixed and required.

Enumerated values for attributes

<xs:element name=""> <xs:complexType mixed="true"> <xs:attribute name="x" type="xs:string"> <restriction base="xs:string"> <enumeration value="p"/> <enumeration value="q"/> </restriction> </xs:attribute> </xs:complexType> </xs:element>
to top

Document Structure

Focus on declaring child elements.
Each child is declared separately, as a top-level element.
References to child declarations are via the 'ref' attribute
<xs:element name="a"> ... <xs:element ref="b"> ... </xs:element> <xs:element name="b"> ... </xs:element>
If the schema targets a namespace, and a prefix is used, the ref must include the prefix, though the name attribute for the element definition does not.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ss="http://www.ouch.com/namespaces/ssss"> <xs:element name="a"> ... <xs:element ref="ss:b"/> ... </xs:element> <xs:element name="b"> .. </xs:element> </xs:schema>
Child elements must be declared inside an anonymous complexType element.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ss="http://www.ouch.com/namespaces/ssss"> <xs:element name="a"> <xs:complexType> ... </xs:complexType> </xs:element> </xs:schema>

Sequences of child elements

Sequences are used to declare a sequence of children in a fixed order.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ss="http://www.ouch.com/namespaces/ssss"> <xs:element name="a"> <xs:complexType> <xs:sequence> <element ref="ss:x"/> <element ref="ss:y"/> <element ref="ss:z"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="x">...</xs:element> <xs:element name="y">...</xs:element> <xs:element name="z">...</xs:element> </xs:schema>
Each child must occur exactly once, in the specified order.

Optional and repeatable child elements

Use the 'minOccurs' and 'maxOccurs' attributes.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ss="http://www.ouch.com/namespaces/sss"> <xs:element name="a"> <xs:complexType> <xs:sequence> <element ref="ss:x"/> <element ref="ss:y" minOccurs="0" maxOccurs="1"/> <element ref="ss:z" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="x">...</xs:element> <xs:element name="y">...</xs:element> <xs:element name="z">...</xs:element> </xs:schema>
An a has one x, an optional y and an arbitrary number of z's.
The default value is 1 for both minOccurs and maxOccurs.

Alternative elements

Use the 'choice' element to list a set of elements, exactly one of which may appear.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ss="math://www.ouch.com/namespaces/ssss"> <xs:element name="a"> <xs:complexType> <xs:choice> <element ref="ss:x"/> <element ref="ss:y"/> </xs:choice> </xs:complexType> </xs:element> <xs:element name="x">...</xs:element> <xs:element name="y">...</xs:element> </xs:schema>
The a item may have an x child or a y child.

Nested sequence and choice constructions

Sequences and choices can be nested, and each can have minOccurs and maxOccurs attributes.
<xs:element name="a"> <xs:complexType> <xs:choice> <xs:element ref="b"/> <xs:sequence> <xs:element ref="c"/> <xs:element ref="d"/> </xs:sequence> </xs:choice> </xs:complexType> </xs:element>
Here, a can have either one child b, or a pair of children c and d.
<xs:element name="a"> <xs:complexType> <xs:sequence> <xs:element ref="w"> <xs:choice minOccurs="0" maxOccurs="3"> <xs:element ref="x"/> <xs:element ref="y"/> </xs:choice> <xs:element ref="z"/> </xs:choice> </xs:complexType> </xs:element>
The children in this example consiste of one w, followed by 0, 1, 2 or 3 elements, each of which could be an x or a y, followed by one z.

Unordered sequences

<xs:element name="a"> <xs:complexType> <xs:all> <element ref="x"/> <element ref="y"/> <element ref="z"/> </xs:all> </xs:complexType> </xs:element>
Each of p, q, and r must appear as children, but in any order.
The minOccurs attribute can be set to 0 for any child, in order to make it optional. However, the maxOccurs attribute cannot be set to any value greater than 1.

The any element

<xs:element name="a"> <xs:complexType> <xs:sequence> <xs:any/> </xs:sequence> </xs:complexType> </xs:element>
The a element exactly one child, whose element name is not specified.
minOccurs and maxOccurs can also be used:
<xs:element name="a"> <xs:complexType> <xs:sequence> <xs:any minOccurs="1" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element>
This requires at least one child, but arbitrarily many are possible.

Restricting the namespace for any

With the any element, it is possible to specify constraints on the namespace from which it can be drawn.
1. The children of a can be from any namespace:
<xs:element name="a"> <xs:complexType> <xs:sequence> <xs:any/> </xs:sequence> </xs:complexType> </xs:element>
2. The children of b can be from any namespace (same effect as case 1):
<xs:element name="b"> <xs:complexType> <xs:sequence> <xs:any namespace="##any"/> </xs:sequence> </xs:complexType> </xs:element>
3. The children of c can be from the target namespace for the schema:
<xs:element name="c"> <xs:complexType> <xs:sequence> <xs:any namespace="##targetNamespace"/> </xs:sequence> </xs:complexType> </xs:element>
4. The children of d can be from any namespace other than the target namespace for the schema:
<xs:element name="d"> <xs:complexType> <xs:sequence> <xs:any namespace="##other"/> </xs:sequence> </xs:complexType> </xs:element>
5. The children of e can be from the specified namespace:
<xs:element name="e"> <xs:complexType> <xs:sequence> <xs:any namespace="http://www.ouch.com/namespaces/burps"/> </xs:sequence> </xs:complexType> </xs:element>
6. The children of f can be from any of the specified namespaces:
<xs:element name="f"> <xs:complexType> <xs:sequence> <xs:any namespace="http://www.ouch.com/namespaces/hugs http://www.ouch.com/namespaces/kisses"/> </xs:sequence> </xs:complexType> </xs:element>
7. The children of g must be unqualified (only in schema with no target namespace):
<xs:element name="g"> <xs:complexType> <xs:sequence> <xs:any namespace="##local"/> </xs:sequence> </xs:complexType> </xs:element>

Any attribute

The anyAttribute element can be used to permit any attribute.
<xs:element name="a"> <xs:complexType> <xs:attribute name="x" .../> <xs:attribute name="y" .../> <xs:anyAttribute/> </xs:complexType> </xs:element>
anyAttribute stands for 0, 1 or more attributes; it is not possible to specify minOccurs or maxOccurs. So the declaration above says that the a element has an x attribute, a y attribute and arbitrarily many other attributes.
If anyAttribute appears, it must be last in the list of attributes!

Namespaces for anyAttribute

The namespace for anyAttribute can also be defined using the namespace attribute. The ##any, ##other, ##local and ##targetNamespace values are possible.
<xs:element name="a"> <xs:complexType> <xs:attribute name="x" .../> <xs:attribute name="y" .../> <xs:anyAttribute namespace="##other"/> </xs:complexType> </xs:element>
The ##any declaration means that the attributes must come from any namespace.
The ##targetNamespace declaration means that the attributes must come from the target namespace.
The ##other declaration means that the attributes must come from a namespace other than the target namespace.
The ##local declaration is used when there is no target namespace, to indicate that the attribute must come from the default namespace.

Groups

A sequence, choice or all which is used in several declarations can be placed in its own 'group' definition and referenced by the declarations of the containing element.
<xs:group name="g"> <xs:complexType> <xs:sequence> <xs:element ref="a"/> <xs:element ref="b"/> <xs:element ref="c"/> </xs:sequence> </xs:complexType> </xs:group> ... <xs:element name="r"> <xs:sequence> <xs:group ref="g"/> </xs:sequence> </xs:element> ... <xs:element name="s"> <xs:sequence> <xs:group ref="g"/> </xs:sequence> </xs:element>
As for element refs, the group refs should include a namespace if the schema targets a document with a namespace.
The group reference can have 'minOccurs' and 'maxOccurs' attributes.
Groups can contain references to other groups, but circular references are forbidden.

Elements with constrained attributes and unconstrained content

Example:
<xs:element name="a"> <xs:complexType mixed="true"> <xs:attribute name="x" type="xs:string"/> <xs:attribute name="y" type="xs:integer"/> </xs:complexType> </xs:element>

Elements with constrained attributes and constrained content

This one seems a bit weird to me:
<xs:element name="a"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:integer"/> <xs:attribute name="x" type="xs:string"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element>
The simpleContent declaration means that the element content will not include other elements, and can be given a type. The base attribute of the extension element defines the content type. The attribute inside the extension element defines the allowed attribute and its type on the parent element. So this declaration means that the e element can have an x attribute of type string, and content of type integer. I'm not sure why the attribute declaration needs to be inside the extension element!

Local element declarations

Elements declared at toplevel (i.e. as children of the schema element) are global and apply to all instances of the element in the entire document.
It is also possible to declare elements locally, in the declaration of another element. In this case, the declarations applies only to elements which are children of the parent element.
<xs:element name="a"> <xs:complexType> <xs:sequence> <xs:element name="y" type="xs:date"/> </xs:sequence> </xs:complexType> </xs:element>
In this case, the y elements only need to be dates when they are children of x elements. Other y's in the document may have different validation.

Global attribute declarations

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:attribute name="x"/> ... <xs:element name="a"> <xs:complexType> <xs:attribute ref="x"/> </xs:complexType> </xs:element> </xs:schema>
This approach doesn't work too well if the instance documents use a namespace with prefix, since the attributes in the instance must use the prefix. For example:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:pk="http://www.ouch.com/namespaces/pooka" targetNamespace="http://www.ouch.com/namespaces/pooka"> <xs:attribute name="x" type="xs:date"/> ... <xs:element name="a"> <xs:complexType> <xs:attribute ref="pk:x"/> </xs:complexType> </xs:element> </xs:schema>
Now a document conforming to this schema must include the namespace prefix on a attributes, since the a attribute has been explicitly added to the namespace.
<pk:root xmnls:pk="http://www.ouch.com/namespaces/pooka"> <a pk:x="2005-03-23"/> </pk:root>

Attribute groups

An attribute group can be declared at toplevel: the group becomes part of the target namespace (if it exists), but the contained attributes don't.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:s="http://www.ouch.com/namespaces/ssss" targetNamespace="http://www.ouch.com/namespaces/pooka"> <xs:attributeGroup name="ag"/> <xs:attribute name="x" type="xs:date"/> <xs:attribute name="y" type="xs:time"/> </xs:attributeGroup> ... <xs:element name="a"> <xs:complexType> <xs:attributeGroup ref="ss:ag"/> </xs:complexType> </xs:element> </xs:schema>
A conforming document does not need the namespace prefix on the attributes.
<pk:root xmnls:pk="http://www.ouch.com/namespaces/pooka"> <a x="2005-03-23" y="10:00:00"/> </pk:root>
Groups can reference other groups.
to top

Big Example

XSD XML
<?xml version='1.0'?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:asi="http://www.alethis.net/namespaces/asi" targetNamespace="http://www.alethis.net/namespaces/asi"> <!-- element with any content --> <xs:element name="root"/> <!-- no attributes, empty --> <xs:element name="a"><xs:complexType/></xs:element> <!-- no attributes, simple content --> <xs:element name="b" type="xs:string"/> <!-- no attributes, arbitrary child elements, no text --> <xs:element name="c"> <xs:complexType> <xs:sequence> <xs:any processContents="skip" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <!-- no attributes, arbitrary child elements and text content --> <xs:element name="d"> <xs:complexType mixed="true"> <xs:sequence> <xs:any processContents="skip" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <!-- attributes, empty element --> <xs:element name="e"> <xs:complexType> <xs:attribute name="ee" type="xs:integer"/> </xs:complexType> </xs:element> <!-- attributes, simple content --> <xs:element name="f"> <xs:complexType mixed="true"> <xs:simpleContent> <xs:extension base="xs:integer"> <xs:attribute name="ff" type="xs:date"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <!-- attributes, arbitrary child elements, no text --> <xs:element name="g"> <xs:complexType> <xs:sequence> <xs:any processContents="skip" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="gg" type="xs:time"/> </xs:complexType> </xs:element> <!-- attributes, arbitrary child elements, and text content --> <xs:element name="h"> <xs:complexType mixed="true"> <xs:sequence> <xs:any processContents="skip" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="hh" type="xs:negativeInteger"/> </xs:complexType> </xs:element> <xs:element name="c1"/> <xs:element name="c2"/> <xs:element name="c3"/> <!-- no attributes, ordered children --> <xs:element name="i"> <xs:complexType> <xs:sequence> <xs:element ref="asi:c1"/> <xs:element ref="asi:c2"/> <xs:element ref="asi:c3"/> </xs:sequence> </xs:complexType> </xs:element> <!-- no attributes, unordered children --> <xs:element name="j"> <xs:complexType> <xs:all> <xs:element ref="asi:c1"/> <xs:element ref="asi:c2"/> <xs:element ref="asi:c3"/> </xs:all> </xs:complexType> </xs:element> <!-- no attributes, alternative children --> <xs:element name="k"> <xs:complexType> <xs:choice> <xs:element ref="asi:c1"/> <xs:element ref="asi:c2"/> <xs:element ref="asi:c3"/> </xs:choice> </xs:complexType> </xs:element> <!-- attributes, constrained children, no text --> <xs:element name="m"> <xs:complexType> <xs:sequence> <xs:element ref="asi:c1"/> <xs:element ref="asi:c2"/> </xs:sequence> <xs:attribute name="mm" type="xs:positiveInteger"/> </xs:complexType> </xs:element> <!-- attributes, constrained children, and text content --> <xs:element name="n"> <xs:complexType mixed="true"> <xs:sequence> <xs:element ref="asi:c1"/> <xs:element ref="asi:c2"/> </xs:sequence> <xs:attribute name="nn" type="xs:gDay"/> </xs:complexType> </xs:element> <!-- children of particular types, in any order --> <xs:element name="o"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element ref="asi:c1"/> <xs:element ref="asi:c2"/> </xs:choice> </xs:complexType> </xs:element> </xs:schema> <?xml version='1.0'?> <asi:root xmlns:asi="http://www.alethis.net/namespaces/asi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.alethis.net/namespaces/asi test.xsd"> <!-- no attributes, empty --> <asi:a/> <!-- no attributes, simple content --> <asi:b>xxx xxx xxx</asi:b> <!-- no attributes, arbitrary child elements, no text --> <asi:c> <xx z='z'>zzz</xx> <y>yyyyy</y> </asi:c> <!-- no attributes, arbitrary child elements and text content --> <asi:d> zzz <xx z='z'>zzz</xx>xxxx <y>yyyyy</y> xxx xxx </asi:d> <!-- attributes, empty element --> <asi:e ee="9999"/> <!-- attributes, simple content --> <asi:f ff="2005-01-01"> 12345 </asi:f> <!-- attributes, arbitrary child elements, no text --> <asi:g gg="10:59:59"> <xx z='z'>zzz</xx> <y>yyyyy</y> </asi:g> <!-- attributes, arbitrary child elements, and text content --> <asi:h hh="-4"> zzz <xx z='z'>zzz</xx>xxxx <y>yyyyy</y> xxx xxx </asi:h> <!-- ordered children --> <asi:i> <asi:c1/> <asi:c2/> <asi:c3/> </asi:i> <!-- unordered children --> <asi:j> <asi:c3/> <asi:c1/> <asi:c2/> </asi:j> <!-- alternative children --> <asi:k> <asi:c2/> </asi:k> <!-- attributes, constrained children, no text --> <asi:m mm="595"> <asi:c1/> <asi:c2/> </asi:m> <!-- attributes, constrained children, and text content --> <asi:n nn="---23"> xxx <asi:c1/> yyy <asi:c2/> zzz </asi:n> <!-- children of particular types, in any order --> <asi:o> <asi:c1/> <asi:c1/> <asi:c2/> <asi:c1/> <asi:c2/> <asi:c2/> <asi:c1/> </asi:o> </asi:root>
to top

Unique and Key

The unique and key declarations both ensure that values are unique across an entire document.
The target data for keys has to exist and be unique; the target value for unique need not exist.
With a key declaration, it is also possible to verify the references to the value exists, as well.
Values can have one component, or multiple components.
Consider a document like this:
<library> <book isbn="5555555555555"> <author>a</author> <title>x</title> </book> <book isbn="6666666666666"> <author>b</author> <title>y</title> </book> <book isbn="7777777777777"> <author>c</author> <title>x</title> </book> <book isbn="9999999999999"> <title>z</title> </book> ... </library>
Use a key to ensure that each book has an isbn, and that there are no duplicates:
<xs:element name="library"> <xs:key name="isbn-key"> <xs:selector xpath="book"/> <xs:field xpath="@isbn"/> <xs:key> </xs:element>
The selector must target elements which are descendants of the element for which the key is defined.
A unique declaration can be used to ensure uniqueness, while still permitting values to be absent.
<xs:element name="library"> <xs:unique name="title-author"> <xs:selector xpath="book"/> <xs:field xpath="title"/> <xs:field xpath="author"/> <xs:unique> </xs:element>
With keys, values which refer to key values can be validated.
<xs:element name="collection"> <xs:keyref refer="isbn-key"> <xs:selector xpath="item"/> <xs:field xpath="@book"/> <xs:keyref> </xs:elements>
Using this, the validator can check that all of the book attributes on item elements actually refer to existing books:
<library> <book isbn="5555555555555"> <author>a</author> <title>x</title> </book> ... <collection> <item book="7777777777777"/> <item book="6666666666666"/> </collection> </library>
to top

Data Types

Primitive types

Name Example/Notes
duration P3Y2M5DT22H16M59.4S
dateTime 2005-03-26T23:15:12.266-05:00
time 23:15:12.266-05:00
date 2003-12-12Z
gYearMonth 2003-05
gYear 2004
gMonthDay --04-30
gDay ---27
gMonth --02--
boolean true
base64Binary B7L30 (see RFC 2045)
hexBinary 7FE20A7
float 23.7E12
double 23.7E349
anyURI www.alethis.net (based on RFC 2396/2732 - can be URL or URN)
QName xs:element
NOTATION PNG
decimal 78
string Hello there!

Built-in numeric types

These are derived from decimal.
Name Example/Notes
integer 456456456456
long 345345345
int 2342343
short 12324
byte 123
nonNegativeInteger 0
unsignedLong 56565656565
unsignedInt 454545454
unsignedShort 61243
unsignedByte 254
positiveInteger 45
nonPositiveInteger -45
negativeInteger -45

Built-in string types

These are derived from string.
Name Example/Notes
normalizedString leading/trailing whitespace removed
token internal strings of whitespace collapsed
language en
NMTOKEN ABC
name yo:buddy
NCNAME buddy
ID fred
IDREF fred
IDREFS fred sally bill
ENTITY e
ENTITIES e f g

Nils

Most of the specified data types will not permit an empty value. To permit empty values, declare them as nillable, and set the xs:nil attribute to true in the document.
In the schema:
<xs:element name="e" type="xs:integer" nillable="true"></xs:element>
In the document:
<e xs:nil="true"></e>
to top

Defining simple types

A named simple types can be created at the top level, for reference in multiple elements. An anonymous simple type can be created inside the declaration of a single element.
<xs:simpleType name="num3"> <xs:restriction base="xs:integer"> <xs:length value="3"/> </xs:restriction> </xs:simpleType> ... <xs:element name="p" type="num3"> ... <xs:element name="q"> <xs:simpleType> <xs:length value="4"/> </xs:simpleType> </xs:element>
Simple types are placed in the target namespace, and so the 'type' attribute must include the namespace prefix if the schema targets a namespace.
Simple types can also be used with attributes.
<xs:simpleType name="num3"> <xs:restriction base="xs:integer"> <xs:length value="3"/> </xs:restriction> </xs:simpleType> ... <xs:element name="q"> <xs:attribute name="a" type="num3"/> <xs:simpleType> <xs:length value="4"/> </xs:simpleType> </xs:element>

Facets

Facets are attributes that can be used to restrict simple type, that is, make them more precise.
Facet Applies to Description
length string types only The length of the value
minLength string types only The minimum length of the value
maxLength string types only The maximum length of the value
pattern all types Regular expression match
enumeration all types, except boolean List of permitted values
whitespace all types List of permitted values
minInclusive numerical types Minimum value, inclusive
minExclusive numerical types Minimum value, exclusive
maxInclusive numerical types Maximum value, inclusive
maxInclusive numerical types Maximum value, exclusive
totalDigits numerical types Total number of digits
fractionDigits numerical types Total number of digits after the decimal point

length

Specifies a fixed number of characters.
<xs:simpleType name="string5"> <xs:restriction base="xs:string"> <xs:length value="5"/> </xs:restriction> </xs:simpleType>

minLength, maxLength

Specifies a minimum or maximum number of characters.
<xs:simpleType name="x"> <xs:restriction base="xs:string"> <xs:minLength value="5"/> </xs:restriction> </xs:simpleType>
It is possible to specify both min and max.
<xs:simpleType name="x"> <xs:restriction base="xs:string"> <xs:minLength value="5"/> <xs:maxLength value="7"/> </xs:restriction> </xs:simpleType>

pattern

Specifies that the value must match a regular expression.
<xs:simpleType name="telephone"> <xs:restriction base="xs:string"> <xs:pattern value="\d{3}-\d{4}"/> </xs:restriction> </xs:simpleType>
The regular expressions are Perl-like.
Here is a very brief overview of the pattern language.
Pattern Example Description
? ab?c zero or one occurrences
+ ab+c one or more repeats
* ab*c zero or more repeats
{ } ab{3}c, ab{4,6}c specifies number of repeats
. a.b any single non-newline character
\ a\*b escapes a pattern operator; use with | . ? * + { } ( ) [ ]
\n, \t, \r a\tb newline, tab, carriage return
[ ] [abcd], [a-z] one of a choice of characters
[^ ] [^abc], [^A-Z] any character except one of a choice
( ) a(bc)*d grouping
| a(b|c|d)e, a(b|cd)e choice of branches
\s a\sb whitespace (space, tab, newline, carriage return)
\S a\Ss non-whitespace
\i \iabc any XML initial name character (_, :, or letter)
\I abc\I any XML non-initial name character
\d abc\d any digit
\D \Dabc any non-digit

enumeration

Specifies a list of possible value.
Basing it on NMTOKEN indicates no spaces allowed.
<xs:simpleType name="colors"> <xs:restriction base="xs:NMTOKEN"> <xs:enumeration value="red"/> <xs:enumeration value="green"/> <xs:enumeration value="blue"/> </xs:restriction> </xs:simpleType>

whiteSpace

Specifies processing on the value.
Options are 'preserve', 'replace' and 'collapse'.
<xs:simpleType name="normal"> <xs:restriction base="xs:string"> <xs:whiteSpace value="collapse"/> </xs:restriction> </xs:simpleType>
'preserve' indicates that whitespace should be preserved.
'replace' indicates that \n, \r and \t should be replaced with spaces.
'collapse' includes 'replace', and also trims leading and trailing spaces.
Non-string values are implicitly 'collapsed' before being processed.

minInclusive, minExclusive, maxInclusive, maxExclusive

Specifies ranges of numerical or date values.
<xs:simpleType name="x"> <xs:restriction base="xs:float"> <xs:minInclusive value="0"/> <xs:maxExclusive value="1"/> </xs:restriction> </xs:simpleType>

totalDigits, fractionDigits

Specifies the maximum number of digits and the maximum number of digits to the right of the decimal point.
Different from length, as it does not count the +, - or . characters.
<xs:simpleType name="x"> <xs:restriction base="xs:decimal"> <xs:totalDigits value="6"/> <xs:fractionDigits value="2"/> </xs:restriction> </xs:simpleType>

Lists

Specifies a list of values, space-separated.
Different from length, as it does not count the +, - or . characters.
<xs:simpleType name="x"> <xs:list itemType="xs:integer"/> </xs:simpleType>
For an element declared like this:
<xs:element name="a" type="x"/>
the following would be accepted:
<a>23 -5 16 0 45 23</a>
Duplicate values are accepted.
Length, minLength and maxLength specify the number of elements in the list.
<xs:simpleType name="xx"> <xs:restriction base="x"> <xs:maxLength value="3"/> </xs:restriction> </xs:simpleType>
This specifies a list of up to 3 integers.

Unions

Specifies a choice of alternative.
<xs:simpleType name="x"> <xs:union memberTypes="xs:gDay xs:gMonthDay xs:date"/> </xs:simpleType>
to top

Complex Types

A complex type can be named (defined at the toplevel), or anonymous (defined inside the declaration of an element.
<xs:complexType name="x"> <xs:sequence> ... </xs:sequence> </xs:complexType> <xs:element name="a" type="x"/> <xs:element name="b"> <xs:complexType name="y"> <xs:sequence> ... </xs:sequence> </xs:complexType> </xs:element>

Derived Complex Types

A complex type can be derived from another by restriction or extension. The complexContent child must be sole child, apart from an annotation element.
In the following, the type y is derived from x by extension.
<xs:complexType name="x"> <xs:sequence> <xs:element ref="a"/> <xs:element ref="b"/> </xs:sequence> </xs:complexType> <xs:complexType name="y"/> <xs:complexContent> <xs:extension base="x"> <xs:element ref="c"/> </xs:extension> </xs:complexContent> </xs:complexType>
For derivation by restriction, the base type is copied, and the conditions are made more restrictive.
<xs:complexType name="x"> <xs:sequence> <xs:element ref="a" minOccurs="0" maxOccurs="unbounded"/> <xs:element ref="b" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="y"/> <xs:complexContent> <xs:restriction base="x"> <xs:element ref="a" minOccurs="1" maxOccurs="1"/> <xs:element ref="b" minOccurs="1" maxOccurs="unbounded"/> </xs:restriction> </xs:complexContent> </xs:complexType>
If there are attributes declared in the base type, they are available in the derived type, even if the declaration is not repeated
An attribute in the base type can be removed from the derived type by copying its declaration, and setting the use to prohibited.

Complex Types derived from Simple Types

A complex type can be derived from a simple type.
This could be useful for adding attributes.
<xs:simpleType name="x" type="xs:decimal"> <xs:complexType name="y"/> <xs:simpleContent> <xs:extension base="x"> <xs:attribute name="p" type="xs:string"/> </xs:extension> </xs:simpleContent> </xs:complexType>
to top