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>
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>
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.
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>
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.
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>
|
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>
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>
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>
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>