MENU
XSD
XML Schema Definition, or W3C XML Schema (WXS), is XML-based. All its elements can have the 'id' attribute as well as other attributes. The name of an XSD file ends with ".xsd".Instead of coding an XSD file from scratch, an XSD inference tool such as those in XMLSpy or OxygenXML can generate an XSD file from an XML file. Such a tool can also be found in Microsoft's XML Schema Definition Tool (XSD.exe), Apache's XMLBeans, Trang, xmlgrid.net, etc.
XSD 1.1 became a W3C Recommendation in April 2012, and remains the current version of XML Schema. It supersedes XSD 1.0 with features such as assertions and conditional type assignment (both covered below), and consists of two parts: Part 1: Structures and Part 2: Datatypes.
Basic Features
The following illustrates the basic features of XSD.<?xml version="1.0"?>
<zoo xmlns="http://www.example.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.com zoo.xsd">
<animal id="l123444">
<name>Mighty</name>
<type>lion</type>
<kg>135</kg>
<imported/>
</animal>
<animal id="b355345">
<name>Lucky</name>
<type>bear</type>
<kg>205</kg>
</animal>
</zoo><?xml version="1.0"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com"
xmlns="http://www.example.com"
elementFormDefault="qualified">
<xs:element name="zoo"><xs:complexType><xs:sequence>
<xs:element name="animal" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="type"><xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="lion"/>
<xs:enumeration value="bear"/>
<xs:enumeration value="tiger"/>
</xs:restriction>
</xs:simpleType></xs:element>
<xs:element name="kg"><xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="10"/>
<xs:maxInclusive value="5000"/>
</xs:restriction>
</xs:simpleType></xs:element>
<xs:element name="imported" minOccurs="0">
<xs:complexType/>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence></xs:complexType></xs:element>
</xs:schema>- attributeFormDefault: 'qualified' or 'unqualified'
- elementFormDefault: 'qualified' or 'unqualified'
- defaultAttributes: the name of a defined attribute group which will be included in each complex type, unless overridden by 'defaultAttributesApply' in complexType.
- blockDefault: '#all' or a list of 'extension', 'restriction', or 'substitution'.
- finalDefault: '#all' or a list of 'extension', 'restriction', or 'substitution', additionally 'list' and 'union'.
- xpathDefaultNamespace: '##local', '##defaultNamespace', '##targetNamespace', or any URI.
- version: a version of the schema.
- default: the default value
- fixed: a fixed value
- form: 'unqualified' indicates that the element is not required to be qualified with the namespace prefix. 'qualified' indicates that the element must be qualified with the namespace prefix. The default is given by the elementFormDefault or attributeFormDefault attribute of the schema element.
- use: 'optional', 'prohibited', or 'required'
- inheritable: 'true' or 'false'
- abstract: 'true' or 'false'
- block: '#all' or a list of 'extension' or 'restriction'. This prevents the element from being a subtype; unlike 'final', a subtype can still be declared.
- final: '#all' or a list of 'extension' or 'restriction'. This prevents type derivation by extension, restriction, or both.
- mixed: 'true' or 'false'
- name: NCName
- defaultAttributesApply: 'true' or 'false'
Multiple XSD files can be specified in the XML file, for example:
| <ns1:root xmlns:ns1="http://example.com/1" xmlns:ns2="http://example.com/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://example.com/1 ns1.xsd http://example.com/2 ns2.xsd"> <ns2:a/> </ns1:root> |
Each namespace used in the instance document is mapped to its own schema file in xsi:schemaLocation, given as pairs of namespace URI and schema location.
Elements Hierarchy (Simplified)
|
schema group, attributeGroup redefine notation import include element alternative simpleType union list restriction (assert) enumeration fractionDigits length {max|min}Exclusive {max|min}Inclusive {max|min}Length pattern totalDigits whiteSpace complexType openContent sequence, choice, all (element) (group) any attribute, anyAttribute (group), (attributeGroup) simpleContent, complexContent (restriction) (assert) extension (assert) assert unique, key, keyref selector field annotation appinfo documentation |
Notes on the hierarchy above: schema is always the document root; annotation can be the child of any element; simpleType can be a child of attribute, element, list, restriction, schema, and union; complexType can be a child of element, redefine, and schema; attribute can be a child of attributeGroup, schema, complexType, restriction (both simpleContent and complexContent), and extension (both simpleContent and complexContent); anyAttribute can be a child of complexType, restriction (both simpleContent and complexContent), extension (both simpleContent and complexContent), and attributeGroup; group can be a child of schema, choice, sequence, all, complexType, restriction, and extension; attributeGroup can be a child of attributeGroup, complexType, schema, restriction, and extension; sequence and choice can be a child of group, choice, sequence, complexType, restriction, and extension; all can be a child of group, complexType, restriction, and extension; restriction can be a child of simpleType, simpleContent, and complexContent.
sequence means that the child elements must appear in the specified order, each occurring one time.choice means that only one of the child elements can appear.
all means that the child elements can appear in any order, each occurring one time.
For element, sequence, choice, all, any, or group, the 'minOccurs' and 'maxOccurs' attributes dictate the minimum and maximum number of times an element (or group of elements) can appear.
Assertions
The following uses assertions to deny certain attribute and element values, as well as to validate the order of the attribute values.<?xml version="1.0" encoding="UTF-8"?>
<Transactions
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="transactions.xsd">
<Transaction OrderID="50">-1000</Transaction>
<Transaction OrderID="60">1000</Transaction>
<Transaction OrderID="70">3000</Transaction>
<Transaction OrderID="300">2000</Transaction>
</Transactions><?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Transactions">
<xs:complexType>
<xs:sequence>
<xs:element name="Transaction"
maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="OrderID"
type="xs:integer"/>
<xs:assert test=
"empty(index-of((8,9,10),@OrderID))"/>
<xs:assert test=
"$value = (-3000 to 3000)"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:assert test="every $x in Transaction satisfies
(empty($x/preceding-sibling::*) or
($x/@OrderID gt
$x/preceding-sibling::*[1]/@OrderID))"/>
</xs:complexType>
</xs:element>
</xs:schema>Annotations, Groups, References, and Restrictions
The following illustrates how to use annotations, groups, references, and restrictions.<?xml version="1.0"?>
<dictionary
xmlns="http://www.example.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.com
dictionary.xsd">
<word id="w5445353" initial="b">
<spelling>beautiful</spelling>
<type>adjective</type>
</word>
<word id="w1222234" initial="t">
<spelling>table</spelling>
<type form="singular">noun</type>
</word>
</dictionary><?xml version="1.0"?>
<!-- dictionary.xsd -->
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com"
xmlns="http://www.example.com"
elementFormDefault="qualified">
<xs:include schemaLocation="dictDef.xsd"/>
<xs:element name="dictionary" type="dType"/>
</xs:schema><?xml version="1.0"?>
<!-- dictDef.xsd -->
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com"
xmlns="http://www.example.com"
elementFormDefault="qualified">
<xs:annotation>
<xs:appinfo source="http://example.com/info/">
Example Note
</xs:appinfo>
<xs:documentation source="http://example.com/info/">
A group, attribute group, or custom
type may be reused multiple times.
</xs:documentation>
</xs:annotation>
<xs:simpleType name="wType">
<xs:restriction base="xs:string">
<xs:enumeration value="noun"/>
<xs:enumeration value="verb"/>
<xs:enumeration value="adjective"/>
</xs:restriction>
</xs:simpleType>
<xs:group name="wSequence">
<xs:sequence>
<xs:element name="spelling"><xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[a-zA-Z ]+"/>
<xs:maxLength value="50"/>
<xs:whiteSpace value="collapse"/>
</xs:restriction>
</xs:simpleType></xs:element>
<xs:element name="type">
<xs:complexType><xs:simpleContent>
<xs:extension base="wType">
<xs:attribute name="form">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="singular"/>
<xs:enumeration value="plural"/>
<xs:enumeration value="present"/>
<xs:enumeration value="past"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent></xs:complexType>
</xs:element>
</xs:sequence>
</xs:group>
<xs:attributeGroup name="wAttributes">
<xs:attribute name="id" type="xs:ID" />
<xs:attribute name="initial" type="xs:NMTOKEN" />
<xs:anyAttribute/>
</xs:attributeGroup>
<xs:complexType name="dType"><xs:sequence>
<xs:element name="word" maxOccurs="999999">
<xs:complexType>
<xs:group ref="wSequence"/>
<xs:attributeGroup ref="wAttributes"/>
</xs:complexType>
</xs:element>
</xs:sequence></xs:complexType>
</xs:schema>include adds an external XSD schema with the same target namespace. To add a schema with a different target namespace, use import instead:
| <xs:import namespace="http://example.com/schema"/> <xs:import schemaLocation="http://example.com/schema"/> |
import brings in a schema with a different target namespace than the importing schema.
For restriction and extension, the base attribute must be specified, and can be either a built-in primitive data type or a custom data type.complexType cannot include both a restriction and an extension. To restrict and declare an attribute for an element at the same time, first declare a restricted simpleType, and use that type as the base for the extension of the element.
anyAttribute allows the element to include attributes not declared by the schema.
complexContent contains an extension or a restriction for a complexType. simpleContent contains an extension or a restriction for a simpleType, or for a complexType containing text only.
Conditional Type Assignment
The following demonstrates conditional type assignment, in which the type of an element depends on one of its attributes. This also shows how to specify XSD versions for the validator, using the vc:minVersion and vc:maxVersion attributes from the XML Schema versioning namespace.<?xml version="1.0" encoding="UTF-8"?>
<integer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="file:///C:/Zend/Apache2/htdocs/xml/integer.xsd"
kind="b">127</integer><?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
vc:minVersion="1.1">
<xs:complexType name="bInt">
<xs:simpleContent>
<xs:extension base="xs:byte">
<xs:attribute name="kind" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="sInt">
<xs:simpleContent>
<xs:extension base="xs:short">
<xs:attribute name="kind" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="iInt">
<xs:simpleContent>
<xs:extension base="xs:int">
<xs:attribute name="kind" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="lInt">
<xs:simpleContent>
<xs:extension base="xs:long">
<xs:attribute name="kind" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="gInt">
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="kind" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name="integer"
vc:minVersion="1.1" vc:maxVersion="3.0">
<xs:alternative test="@kind='b'" type="bInt"/>
<xs:alternative test="@kind='s'" type="sInt"/>
<xs:alternative test="@kind='i'" type="iInt"/>
<xs:alternative test="@kind='l'" type="lInt"/>
<xs:alternative type="gInt"/>
</xs:element>
</xs:schema>Notation, List, Union, and Numeric Restrictions
The following illustrates notation, list, union, dateTime, and numeric restrictions.<?xml version="1.0"?>
<dtList
xmlns="http://www.example.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.com date.xsd">
2013-03-02Z
12:00:00+08:00
2013-03-02T12:00:00+08:00
123
321.444
</dtList><?xml version="1.0"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com"
xmlns="http://www.example.com"
elementFormDefault="qualified">
<xs:notation name="jpeg"
public="image/jpeg" system="viewer.exe" />
<xs:simpleType name="numbers">
<xs:restriction base="xs:decimal">
<xs:totalDigits value="10"/>
<xs:fractionDigits value="3"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="dUnion">
<xs:union memberTypes="xs:date
xs:time
xs:dateTime
numbers"/>
</xs:simpleType>
<xs:element name="dtList">
<xs:simpleType>
<xs:list itemType="dUnion"/>
</xs:simpleType>
</xs:element>
</xs:schema>any, notation, and Mixed Content
The following shows how to declare any element, notation, and 'mixed' content. Here, <nameslist> must start with one single arbitrary element. An element named <description> must appear after another element named <name>, with any number of arbitrarily named elements in between.<?xml version="1.0" encoding="UTF-8"?>
<nameslist
xmlns="http://www.example.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.com
nameslist.xsd">
<group>Famous People</group>
<person>
<name>Bruce</name>
<age>30</age>
<description>He is a real <b>fighter</b>.</description>
</person>
<person>
<name>Stephen</name>
<sex>male</sex>
<status>married</status>
<description>He is a real <b>writer</b>.</description>
</person>
</nameslist><?xml version="1.0"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.example.com"
targetNamespace="http://www.example.com"
elementFormDefault="qualified">
<xs:notation name="jpeg"
public="image/jpeg" system="viewer.exe" />
<xs:element name="nameslist">
<xs:complexType>
<xs:sequence>
<xs:any namespace="##any" processContents="lax"
notQName="name description person"/>
<xs:element name="person" maxOccurs="10">
<xs:complexType>
<xs:openContent>
<xs:any namespace="##any"
processContents="lax"/>
</xs:openContent>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="description">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element name="b" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>A notation describes the format of non-XML data.
A complexType or complexContent with the mixed attribute declared as 'true' can have text around its child elements, i.e. a mixture of elements and text.
openContent can have the 'mode' attribute, which can have a value of 'none', 'interleave', or 'suffix'. The default is 'interleave'.
any and anyAttribute can have the following attributes:
- namespace:
- ##any - from any namespace (default)
- ##other - any namespace that is not the namespace of the parent element
- ##local - no namespace
- ##targetNamespace - the namespace of the parent element
- a space-delimited list of {namespace URIs, ##targetNamespace, ##local}
- notNamespace:
- ##targetNamespace
- ##local
- a list of anyURI and the previous two
- notQName:
- a list of QName, ##defined, or ##definedSibling
- processContents:
- strict - the processor must obtain the schema for the required namespaces and validate the elements (default)
- lax - same as strict; if the schema cannot be obtained, no errors will occur
- skip - the processor does not attempt to validate any elements from the specified namespaces
redefine
redefine allows simple and complex types, groups, and attribute groups to be redefined from an external schema. This construct is deprecated in XSD 1.1.<?xml version="1.0"?>
<item
xmlns="http://www.example.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.com item.xsd">
<name>ruler</name>
<price>1.00</price>
</item><?xml version="1.0"?>
<!-- item.xsd -->
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com"
xmlns="http://www.example.com"
elementFormDefault="qualified">
<xs:redefine schemaLocation="item2.xsd">
<xs:complexType name="iDetails">
<xs:complexContent>
<xs:extension base="iDetails">
<xs:sequence>
<xs:element name="price"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:redefine>
<xs:element name="item" type="iDetails"/>
</xs:schema><?xml version="1.0"?>
<!-- item2.xsd -->
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com"
xmlns="http://www.example.com"
elementFormDefault="qualified">
<xs:complexType name="iDetails">
<xs:sequence>
<xs:element name="name"/>
</xs:sequence>
</xs:complexType>
</xs:schema>override
override works in a similar way to redefine.<?xml version="1.0"?>
<item
xmlns="http://www.example.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.com item.xsd">
<price>1.00</price>
</item><?xml version="1.0"?>
<!-- item.xsd -->
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.example.com"
targetNamespace="http://www.example.com"
elementFormDefault="qualified">
<xs:override schemaLocation="item2.xsd">
<xs:complexType name="iDetails">
<xs:sequence>
<xs:element name="price"/>
</xs:sequence>
</xs:complexType>
</xs:override>
<xs:element name="item" type="iDetails"/>
</xs:schema><?xml version="1.0"?>
<!-- item2.xsd -->
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.example.com"
targetNamespace="http://www.example.com"
elementFormDefault="qualified">
<xs:complexType name="iDetails">
<xs:sequence>
<xs:element name="name"/>
</xs:sequence>
</xs:complexType>
</xs:schema>Substitution Groups
The following demonstrates substitution. All three XML documents below are valid against the same schema.<?xml version="1.0" ?>
<section
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="body.xsd">
<p>Hello World!</p>
</section><?xml version="1.0" ?>
<body
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="body.xsd">
<div>Hello World!</div>
</body><?xml version="1.0" ?>
<section
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="body.xsd">
<div>Hello World!</div>
</section><xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:complexType name="sContent">
<xs:sequence>
<xs:element ref="p"/>
</xs:sequence>
</xs:complexType>
<xs:element name="section" type="sContent"/>
<xs:element name="body" substitutionGroup="section"/>
<xs:element name="p" type="xs:string"/>
<xs:element name="span" type="xs:string"/>
<xs:element name="div" substitutionGroup="p span"/>
</xs:schema>- abstract: true or false
- block: #all or a list that is a subset of substitution, extension, or restriction
- final: #all or a list that is a subset of extension or restriction
Identity Constraints
The following example illustrates identity constraints. Each child of <items> must have a 'number' attribute whose value matches one of the unique product numbers. Each <product> element must have a <number> child whose value is unique.<?xml version="1.0" ?>
<shipment
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shipment.xsd">
<number>987QWERTY</number>
<items>
<thermometer number="876">
<quantity>1</quantity>
<color value="blue"/>
</thermometer>
<thermometer number="876">
<quantity>1</quantity>
<color value="sage"/>
</thermometer>
<pump number="432">
<quantity>1</quantity>
</pump>
</items>
<products>
<product>
<number>876</number>
<name>TM-902C K Type Digital Thermometer</name>
<price currency="USD">14.99</price>
</product>
<product>
<number>432</number>
<name>3CFM 1/4HP Rotary Vane Vacuum Pump</name>
<price currency="USD">59.99</price>
</product>
</products>
</shipment><xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="shipment" type="OrderType">
<xs:keyref name="prodNumKeyRef" refer="prodNumKey">
<xs:selector xpath="items/*"/>
<xs:field xpath="@number"/>
</xs:keyref>
<xs:key name="prodNumKey">
<xs:selector xpath=".//product"/>
<xs:field xpath="number"/>
</xs:key>
</xs:element>
<xs:complexType name="OrderType">
<xs:sequence>
<xs:element name="number" type="xs:string"/>
<xs:element name="items" type="ItemsType"/>
<xs:element name="products" type="ProductsType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ItemsType">
<xs:choice maxOccurs="unbounded">
<xs:element name="thermometer"
type="ProductOrderType"/>
<xs:element name="pump" type="ProductOrderType"/>
</xs:choice>
</xs:complexType>
<xs:complexType name="ProductOrderType">
<xs:sequence>
<xs:element name="quantity" type="xs:integer"/>
<xs:element name="color" type="ColorType"
minOccurs="0"/>
</xs:sequence>
<xs:attribute name="number" type="xs:integer"/>
</xs:complexType>
<xs:complexType name="ProductsType">
<xs:sequence>
<xs:element name="product" type="ProductType"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ProductType">
<xs:sequence>
<xs:element name="number" type="xs:integer"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="price" type="PriceType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ColorType">
<xs:attribute name="value" type="xs:string"/>
</xs:complexType>
<xs:complexType name="PriceType">
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="currency" type="xs:token"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:schema>