XML Schema Creation and Usage Guide
XML Schema Creation and Usage Guide
An XML Schema describes the structure of an XML document. In this tutorial you will learn how to create XML Schemas, why XML Schemas are more powerful than DTDs, and how to use XML Schema in your application. Start learning XML Schema now!
Next Chapter
XML Schema is an XML-based alternative to DTD. An XML schema describes the structure of an XML document. The XML Schema language is also referred to as XML Schema Definition (XSD).
If you want to study these subjects first, find the tutorials on our Home page.
Even if documents are well-formed they can still contain errors, and those errors can have serious consequences.
Think of the following situation: you order 5 gross of laser printers, instead of 5 laser printers. With XML Schemas, most of these errors can be caught by your validating software.
A DTD File
The following example is a DTD file called "note.dtd" that defines the elements of the XML document above ("note.xml"): <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT note (to, from, heading, body)> to (#PCDATA)> from (#PCDATA)> heading (#PCDATA)> body (#PCDATA)>
The first line defines the note element to have four child elements: "to, from, heading, body". Line 2-5 defines the to, from, heading, body elements to be of type "#PCDATA".
An XML Schema
The following example is an XML Schema file called "note.xsd" that defines the elements of the XML document above ("note.xml"): <?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3schools.com" xmlns="http://www.w3schools.com" elementFormDefault="qualified"> <xs:element name="note"> <xs:complexType> <xs:sequence> <xs:element name="to" type="xs:string"/> <xs:element name="from" type="xs:string"/> <xs:element name="heading" type="xs:string"/> <xs:element name="body" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> The note element is a complex type because it contains other elements. The other elements (to, from, heading, body) are simple types because they do not contain other elements. You will learn more about simple and complex types in the following chapters.
A Reference to a DTD
This XML document has a reference to a DTD: <?xml version="1.0"?> <!DOCTYPE note SYSTEM "http://www.w3schools.com/dtd/note.dtd"> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note>
<?xml version="1.0"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3schools.com" xmlns="http://www.w3schools.com" elementFormDefault="qualified"> ... ... </xs:schema> The following fragment: xmlns:xs="http://www.w3.org/2001/XMLSchema" indicates that the elements and data types used in the schema come from the "http://www.w3.org/2001/XMLSchema" namespace. It also specifies that the elements and data types that come from the "http://www.w3.org/2001/XMLSchema" namespace should be prefixed with xs: This fragment: targetNamespace="http://www.w3schools.com" indicates that the elements defined by this schema (note, to, from, heading, body.) come from the "http://www.w3schools.com" namespace. This fragment: xmlns="http://www.w3schools.com" indicates that the default namespace is "http://www.w3schools.com". This fragment: elementFormDefault="qualified" indicates that any elements used by the XML instance document which were declared in this schema must be namespace qualified.
xsi:schemaLocation="http://www.w3schools.com note.xsd"> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> The following fragment: xmlns="http://www.w3schools.com" specifies the default namespace declaration. This declaration tells the schema-validator that all the elements used in this XML document are declared in the "http://www.w3schools.com" namespace. Once you have the XML Schema Instance namespace available: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" you can use the schemaLocation attribute. This attribute has two values, separated by a space. The first value is the namespace to use. The second value is the location of the XML schema to use for that namespace: xsi:schemaLocation="http://www.w3schools.com note.xsd"
XML Schemas define the elements of your XML files. A simple element is an XML element that contains only text. It cannot contain any other elements or attributes.
However, the "only text" restriction is quite misleading. The text can be of many different types. It can be one of the types included in the XML Schema definition (boolean, string, date, etc.), or it can be a custom type that you can define yourself. You can also add restrictions (facets) to a data type in order to limit its content, or you can require the data to match a specific pattern.
Example
Here are some XML elements: <lastname>Refsnes</lastname> <age>36</age> <dateborn>1970-03-27</dateborn> And here are the corresponding simple element definitions: <xs:element name="lastname" type="xs:string"/> <xs:element name="age" type="xs:integer"/> <xs:element name="dateborn" type="xs:date"/>
A default value is automatically assigned to the element when no other value is specified. In the following example the default value is "red": <xs:element name="color" type="xs:string" default="red"/> A fixed value is also automatically assigned to the element, and you cannot specify another value. In the following example the fixed value is "red": <xs:element name="color" type="xs:string" fixed="red"/>
XSD Attributes
Previous Next Chapter
What is an Attribute?
Simple elements cannot have attributes. If an element has attributes, it is considered to be of a complex type. But the attribute itself is always declared as a simple type.
xs:time
Example
Here is an XML element with an attribute: <lastname lang="EN">Smith</lastname> And here is the corresponding attribute definition: <xs:attribute name="lang" type="xs:string"/>
Restrictions on Content
When an XML element or attribute has a data type defined, it puts restrictions on the element's or attribute's content. If an XML element is of type "xs:date" and contains a string like "Hello World", the element will not validate. With XML Schemas, you can also add your own restrictions to your XML elements and attributes. These restrictions are called facets. You can read more about facets in the next chapter.
XSD Restrictions/Facets
Previous Next Chapter
Restrictions are used to define acceptable values for XML elements or attributes. Restrictions on XML elements are called facets.
Restrictions on Values
The following example defines an element called "age" with a restriction. The value of age cannot be lower than 0 or greater than 120: <xs:element name="age"> <xs:simpleType> <xs:restriction base="xs:integer"> <xs:minInclusive value="0"/> <xs:maxInclusive value="120"/> </xs:restriction> </xs:simpleType> </xs:element>
The example below defines an element called "car" with a restriction. The only acceptable values are: Audi, Golf, BMW: <xs:element name="car"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="Audi"/> <xs:enumeration value="Golf"/> <xs:enumeration value="BMW"/> </xs:restriction> </xs:simpleType> </xs:element> The example above could also have been written like this: <xs:element name="car" type="carType"/> <xs:simpleType name="carType"> <xs:restriction base="xs:string"> <xs:enumeration value="Audi"/> <xs:enumeration value="Golf"/> <xs:enumeration value="BMW"/> </xs:restriction> </xs:simpleType> Note: In this case the type "carType" can be used by other elements because it is not a part of the "car" element.
<xs:element name="initials"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="[A-Z][A-Z][A-Z]"/> </xs:restriction> </xs:simpleType> </xs:element> The next example also defines an element called "initials" with a restriction. The only acceptable value is THREE of the LOWERCASE OR UPPERCASE letters from a to z: <xs:element name="initials"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="[a-zA-Z][a-zA-Z][a-zA-Z]"/> </xs:restriction> </xs:simpleType> </xs:element> The next example defines an element called "choice" with a restriction. The only acceptable value is ONE of the following letters: x, y, OR z: <xs:element name="choice"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="[xyz]"/> </xs:restriction> </xs:simpleType> </xs:element> The next example defines an element called "prodid" with a restriction. The only acceptable value is FIVE digits in a sequence, and each digit must be in a range from 0 to 9: <xs:element name="prodid"> <xs:simpleType> <xs:restriction base="xs:integer"> <xs:pattern value="[0-9][0-9][0-9][0-9][0-9]"/> </xs:restriction> </xs:simpleType> </xs:element>
<xs:element name="letter"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="([a-z])*"/> </xs:restriction> </xs:simpleType> </xs:element> The next example also defines an element called "letter" with a restriction. The acceptable value is one or more pairs of letters, each pair consisting of a lower case letter followed by an upper case letter. For example, "sToP" will be validated by this pattern, but not "Stop" or "STOP" or "stop": <xs:element name="letter"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="([a-z][A-Z])+"/> </xs:restriction> </xs:simpleType> </xs:element> The next example defines an element called "gender" with a restriction. The only acceptable value is male OR female: <xs:element name="gender"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="male|female"/> </xs:restriction> </xs:simpleType> </xs:element> The next example defines an element called "password" with a restriction. There must be exactly eight characters in a row and those characters must be lowercase or uppercase letters from a to z, or a number from 0 to 9: <xs:element name="password"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="[a-zA-Z0-9]{8}"/> </xs:restriction> </xs:simpleType> </xs:element>
To specify how whitespace characters should be handled, we would use the whiteSpace constraint. This example defines an element called "address" with a restriction. The whiteSpace constraint is set to "preserve", which means that the XML processor WILL NOT remove any white space characters: <xs:element name="address"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:whiteSpace value="preserve"/> </xs:restriction> </xs:simpleType> </xs:element> This example also defines an element called "address" with a restriction. The whiteSpace constraint is set to "replace", which means that the XML processor WILL REPLACE all white space characters (line feeds, tabs, spaces, and carriage returns) with spaces: <xs:element name="address"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:whiteSpace value="replace"/> </xs:restriction> </xs:simpleType> </xs:element> This example also defines an element called "address" with a restriction. The whiteSpace constraint is set to "collapse", which means that the XML processor WILL REMOVE all white space characters (line feeds, tabs, spaces, carriage returns are replaced with spaces, leading and trailing spaces are removed, and multiple spaces are reduced to a single space): <xs:element name="address"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:whiteSpace value="collapse"/> </xs:restriction> </xs:simpleType> </xs:element>
Restrictions on Length
To limit the length of a value in an element, we would use the length, maxLength, and minLength constraints.
This example defines an element called "password" with a restriction. The value must be exactly eight characters: <xs:element name="password"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:length value="8"/> </xs:restriction> </xs:simpleType> </xs:element> This example defines another element called "password" with a restriction. The value must be minimum five characters and maximum eight characters: <xs:element name="password"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:minLength value="5"/> <xs:maxLength value="8"/> </xs:restriction> </xs:simpleType> </xs:element>
Specifies the maximum number of decimal places allowed. Must be equal to or greater tha
Specifies the exact number of characters or list items allowed. Must be equal to or greater Specifies the upper bounds for numeric values (the value must be less than this value)
Specifies the upper bounds for numeric values (the value must be less than or equal to th
Specifies the maximum number of characters or list items allowed. Must be equal to or gr zero
Specifies the lower bounds for numeric values (the value must be greater than this value)
Specifies the lower bounds for numeric values (the value must be greater than or equal to
Specifies the minimum number of characters or list items allowed. Must be equal to or gre zero Defines the exact sequence of characters that are acceptable Specifies the exact number of digits allowed. Must be greater than zero Specifies how white space (line feeds, tabs, spaces, and carriage returns) is handled
<product pid="1345"/> A complex XML element, "employee", which contains only other elements: <employee> <firstname>John</firstname> <lastname>Smith</lastname> </employee> A complex XML element, "food", which contains only text: <food type="dessert">Ice cream</food> A complex XML element, "description", which contains both elements and text: <description> It happened on <date lang="norwegian">03.03.99</date> .... </description>
<xs:element name="employee" type="personinfo"/> <xs:complexType name="personinfo"> <xs:sequence> <xs:element name="firstname" type="xs:string"/> <xs:element name="lastname" type="xs:string"/> </xs:sequence> </xs:complexType> If you use the method described above, several elements can refer to the same complex type, like this: <xs:element name="employee" type="personinfo"/> <xs:element name="student" type="personinfo"/> <xs:element name="member" type="personinfo"/> <xs:complexType name="personinfo"> <xs:sequence> <xs:element name="firstname" type="xs:string"/> <xs:element name="lastname" type="xs:string"/> </xs:sequence> </xs:complexType> You can also base a complex element on an existing complex element and add some elements, like this: <xs:element name="employee" type="fullpersoninfo"/> <xs:complexType name="personinfo"> <xs:sequence> <xs:element name="firstname" type="xs:string"/> <xs:element name="lastname" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:complexType name="fullpersoninfo"> <xs:complexContent> <xs:extension base="personinfo"> <xs:sequence> <xs:element name="address" type="xs:string"/> <xs:element name="city" type="xs:string"/> <xs:element name="country" type="xs:string"/> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType>
An "elements-only" complex type contains an element that contains only other elements.
<shoesize country="france">35</shoesize> The following example declares a complexType, "shoesize". The content is defined as an integer value, and the "shoesize" element also contains an attribute named "country": <xs:element name="shoesize"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:integer"> <xs:attribute name="country" type="xs:string" /> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> We could also give the complexType element a name, and let the "shoesize" element have a type attribute that refers to the name of the complexType (if you use this method, several elements can refer to the same complex type): <xs:element name="shoesize" type="shoetype"/> <xs:complexType name="shoetype"> <xs:simpleContent> <xs:extension base="xs:integer"> <xs:attribute name="country" type="xs:string" /> </xs:extension> </xs:simpleContent> </xs:complexType>
A mixed complex type element can contain attributes, elements, and text.
<letter> Dear Mr.<name>John Smith</name>. Your order <orderid>1032</orderid> will be shipped on <shipdate>2001-07-13</shipdate>. </letter> The following schema declares the "letter" element: <xs:element name="letter"> <xs:complexType mixed="true"> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="orderid" type="xs:positiveInteger"/> <xs:element name="shipdate" type="xs:date"/> </xs:sequence> </xs:complexType> </xs:element> Note: To enable character data to appear between the child-elements of "letter", the mixed attribute must be set to "true". The <xs:sequence> tag means that the elements defined (name, orderid and shipdate) must appear in that order inside a "letter" element. We could also give the complexType element a name, and let the "letter" element have a type attribute that refers to the name of the complexType (if you use this method, several elements can refer to the same complex type): <xs:element name="letter" type="lettertype"/> <xs:complexType name="lettertype" mixed="true"> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="orderid" type="xs:positiveInteger"/> <xs:element name="shipdate" type="xs:date"/> </xs:sequence> </xs:complexType>
XSD Indicators
Previous Next Chapter
Indicators
There are seven indicators: Order indicators: All Choice Sequence
Order Indicators
Order indicators are used to define the order of the elements.
All Indicator
The <all> indicator specifies that the child elements can appear in any order, and that each child element must occur only once: <xs:element name="person"> <xs:complexType> <xs:all> <xs:element name="firstname" type="xs:string"/> <xs:element name="lastname" type="xs:string"/> </xs:all> </xs:complexType> </xs:element> Note: When using the <all> indicator you can set the <minOccurs> indicator to 0 or 1 and the <maxOccurs> indicator can only be set to 1 (the <minOccurs> and <maxOccurs> are described later).
Choice Indicator
The <choice> indicator specifies that either one child element or another can occur:
<xs:element name="person"> <xs:complexType> <xs:choice> <xs:element name="employee" type="employee"/> <xs:element name="member" type="member"/> </xs:choice> </xs:complexType> </xs:element>
Sequence Indicator
The <sequence> indicator specifies that the child elements must appear in a specific order: <xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element name="firstname" type="xs:string"/> <xs:element name="lastname" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element>
Occurrence Indicators
Occurrence indicators are used to define how often an element can occur. Note: For all "Order" and "Group" indicators (any, all, choice, sequence, group name, and group reference) the default value for maxOccurs and minOccurs is 1.
maxOccurs Indicator
The <maxOccurs> indicator specifies the maximum number of times an element can occur: <xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element name="full_name" type="xs:string"/> <xs:element name="child_name" type="xs:string" maxOccurs="10"/> </xs:sequence> </xs:complexType> </xs:element>
The example above indicates that the "child_name" element can occur a minimum of one time (the default value for minOccurs is 1) and a maximum of ten times in the "person" element.
minOccurs Indicator
The <minOccurs> indicator specifies the minimum number of times an element can occur: <xs:element name="person"> <xs:complexType> <xs:sequence> <xs:element name="full_name" type="xs:string"/> <xs:element name="child_name" type="xs:string" maxOccurs="10" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element> The example above indicates that the "child_name" element can occur a minimum of zero times and a maximum of ten times in the "person" element. Tip: To allow an element to appear an unlimited number of times, use the maxOccurs="unbounded" statement: A working example: An XML file called "Myfamily.xml": <?xml version="1.0" encoding="ISO-8859-1"?> <persons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="family.xsd"> <person> <full_name>Hege Refsnes</full_name> <child_name>Cecilie</child_name> </person> <person> <full_name>Tove Refsnes</full_name> <child_name>Hege</child_name> <child_name>Stale</child_name> <child_name>Jim</child_name> <child_name>Borge</child_name> </person> <person> <full_name>Stale Refsnes</full_name> </person>
</persons> The XML file above contains a root element named "persons". Inside this root element we have defined three "person" elements. Each "person" element must contain a "full_name" element and it can contain up to five "child_name" elements. Here is the schema file "family.xsd": <?xml version="1.0" encoding="ISO-8859-1"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xs:element name="persons"> <xs:complexType> <xs:sequence> <xs:element name="person" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="full_name" type="xs:string"/> <xs:element name="child_name" type="xs:string" minOccurs="0" maxOccurs="5"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
Group Indicators
Group indicators are used to define related sets of elements.
Element Groups
Element groups are defined with the group declaration, like this: <xs:group name="groupname"> ... </xs:group>
You must define an all, choice, or sequence element inside the group declaration. The following example defines a group named "persongroup", that defines a group of elements that must occur in an exact sequence: <xs:group name="persongroup"> <xs:sequence> <xs:element name="firstname" type="xs:string"/> <xs:element name="lastname" type="xs:string"/> <xs:element name="birthday" type="xs:date"/> </xs:sequence> </xs:group> After you have defined a group, you can reference it in another definition, like this: <xs:group name="persongroup"> <xs:sequence> <xs:element name="firstname" type="xs:string"/> <xs:element name="lastname" type="xs:string"/> <xs:element name="birthday" type="xs:date"/> </xs:sequence> </xs:group> <xs:element name="person" type="personinfo"/> <xs:complexType name="personinfo"> <xs:sequence> <xs:group ref="persongroup"/> <xs:element name="country" type="xs:string"/> </xs:sequence> </xs:complexType>
Attribute Groups
Attribute groups are defined with the attributeGroup declaration, like this: <xs:attributeGroup name="groupname"> ... </xs:attributeGroup> The following example defines an attribute group named "personattrgroup": <xs:attributeGroup name="personattrgroup"> <xs:attribute name="firstname" type="xs:string"/> <xs:attribute name="lastname" type="xs:string"/> <xs:attribute name="birthday" type="xs:date"/> </xs:attributeGroup> After you have defined an attribute group, you can reference it in another definition, like this:
<xs:attributeGroup name="personattrgroup"> <xs:attribute name="firstname" type="xs:string"/> <xs:attribute name="lastname" type="xs:string"/> <xs:attribute name="birthday" type="xs:date"/> </xs:attributeGroup> <xs:element name="person"> <xs:complexType> <xs:attributeGroup ref="personattrgroup"/> </xs:complexType> </xs:element>
The <any> element enables us to extend the XML document with elements not specified by the schema!
<?xml version="1.0" encoding="ISO-8859-1"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.w3schools.com" xmlns="http://www.w3schools.com" elementFormDefault="qualified"> <xs:element name="children"> <xs:complexType> <xs:sequence> <xs:element name="childname" type="xs:string" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> The XML file below (called "Myfamily.xml"), uses components from two different schemas; "family.xsd" and "children.xsd": <?xml version="1.0" encoding="ISO-8859-1"?> <persons xmlns="http://www.microsoft.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.microsoft.com family.xsd http://www.w3schools.com children.xsd"> <person> <firstname>Hege</firstname> <lastname>Refsnes</lastname> <children> <childname>Cecilie</childname> </children> </person> <person> <firstname>Stale</firstname> <lastname>Refsnes</lastname> </person> </persons> The XML file above is valid because the schema "family.xsd" allows us to extend the "person" element with an optional element after the "lastname" element. The <any> and <anyAttribute> elements are used to make EXTENSIBLE documents! They allow documents to contain additional elements that are not declared in the main XML schema.
The <anyAttribute> element enables us to extend the XML document with attributes not specified by the schema!
</xs:restriction> </xs:simpleType> </xs:attribute> </xs:schema> The XML file below (called "Myfamily.xml"), uses components from two different schemas; "family.xsd" and "attribute.xsd": <?xml version="1.0" encoding="ISO-8859-1"?> <persons xmlns="http://www.microsoft.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:SchemaLocation="http://www.microsoft.com family.xsd http://www.w3schools.com attribute.xsd"> <person gender="female"> <firstname>Hege</firstname> <lastname>Refsnes</lastname> </person> <person gender="male"> <firstname>Stale</firstname> <lastname>Refsnes</lastname> </person> </persons> The XML file above is valid because the schema "family.xsd" allows us to add an attribute to the "person" element. The <any> and <anyAttribute> elements are used to make EXTENSIBLE documents! They allow documents to contain additional elements that are not declared in the main XML schema.
Element Substitution
Let's say that we have users from two different countries: England and Norway. We would like the ability to let the user choose whether he or she would like to use the Norwegian element names or the English element names in the XML document. To solve this problem, we could define a substitutionGroup in the XML schema. First, we declare a head element and then we declare the other elements which state that they are substitutable for the head element. <xs:element name="name" type="xs:string"/> <xs:element name="navn" substitutionGroup="name"/> In the example above, the "name" element is the head element and the "navn" element is substitutable for "name". Look at this fragment of an XML schema: <xs:element name="name" type="xs:string"/> <xs:element name="navn" substitutionGroup="name"/> <xs:complexType name="custinfo"> <xs:sequence> <xs:element ref="name"/> </xs:sequence> </xs:complexType> <xs:element name="customer" type="custinfo"/> <xs:element name="kunde" substitutionGroup="customer"/> A valid XML document (according to the schema above) could look like this: <customer> <name>John Smith</name> </customer> or like this: <kunde> <navn>John Smith</navn> </kunde>
To prevent other elements from substituting with a specified element, use the block attribute: <xs:element name="name" type="xs:string" block="substitution"/> Look at this fragment of an XML schema: <xs:element name="name" type="xs:string" block="substitution"/> <xs:element name="navn" substitutionGroup="name"/> <xs:complexType name="custinfo"> <xs:sequence> <xs:element ref="name"/> </xs:sequence> </xs:complexType> <xs:element name="customer" type="custinfo" block="substitution"/> <xs:element name="kunde" substitutionGroup="customer"/> A valid XML document (according to the schema above) looks like this: <customer> <name>John Smith</name> </customer> BUT THIS IS NO LONGER VALID: <kunde> <navn>John Smith</navn> </kunde>
Using substitutionGroup
The type of the substitutable elements must be the same as, or derived from, the type of the head element. If the type of the substitutable element is the same as the type of the head element you will not have to specify the type of the substitutable element. Note that all elements in the substitutionGroup (the head element and the substitutable elements) must be declared as global elements, otherwise it will not work!
Global elements are elements that are immediate children of the "schema" element! Local elements are elements nested within other elements.
An XSD Example
Previous Next Chapter
This chapter will demonstrate how to write an XML Schema. You will also learn that a schema can be written in different ways.
An XML Document
Let's have a look at this XML document called "shiporder.xml": <?xml version="1.0" encoding="ISO-8859-1"?> <shiporder orderid="889923" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="shiporder.xsd"> <orderperson>John Smith</orderperson> <shipto> <name>Ola Nordmann</name> <address>Langgt 23</address> <city>4000 Stavanger</city> <country>Norway</country> </shipto> <item> <title>Empire Burlesque</title> <note>Special Edition</note> <quantity>1</quantity> <price>10.90</price> </item> <item> <title>Hide your heart</title> <quantity>1</quantity> <price>9.90</price> </item> </shiporder> The XML document above consists of a root element, "shiporder", that contains a required attribute called "orderid". The "shiporder" element contains three different child elements:
"orderperson", "shipto" and "item". The "item" element appears twice, and it contains a "title", an optional "note" element, a "quantity", and a "price" element. The line above: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" tells the XML parser that this document should be validated against a schema. The line: xsi:noNamespaceSchemaLocation="shiporder.xsd" specifies WHERE the schema resides (here it is in the same folder as "shiporder.xml").
<xs:element name="shipto"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="address" type="xs:string"/> <xs:element name="city" type="xs:string"/> <xs:element name="country" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> With schemas we can define the number of possible occurrences for an element with the maxOccurs and minOccurs attributes. maxOccurs specifies the maximum number of occurrences for an element and minOccurs specifies the minimum number of occurrences for an element. The default value for both maxOccurs and minOccurs is 1! Now we can define the "item" element. This element can appear multiple times inside a "shiporder" element. This is specified by setting the maxOccurs attribute of the "item" element to "unbounded" which means that there can be as many occurrences of the "item" element as the author wishes. Notice that the "note" element is optional. We have specified this by setting the minOccurs attribute to zero: <xs:element name="item" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="title" type="xs:string"/> <xs:element name="note" type="xs:string" minOccurs="0"/> <xs:element name="quantity" type="xs:positiveInteger"/> <xs:element name="price" type="xs:decimal"/> </xs:sequence> </xs:complexType> </xs:element> We can now declare the attribute of the "shiporder" element. Since this is a required attribute we specify use="required". Note: The attribute declarations must always come last: <xs:attribute name="orderid" type="xs:string" use="required"/> Here is the complete listing of the schema file called "shiporder.xsd": <?xml version="1.0" encoding="ISO-8859-1" ?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="shiporder"> <xs:complexType> <xs:sequence> <xs:element name="orderperson" type="xs:string"/> <xs:element name="shipto">
<xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="address" type="xs:string"/> <xs:element name="city" type="xs:string"/> <xs:element name="country" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="item" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="title" type="xs:string"/> <xs:element name="note" type="xs:string" minOccurs="0"/> <xs:element name="quantity" type="xs:positiveInteger"/> <xs:element name="price" type="xs:decimal"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="orderid" type="xs:string" use="required"/> </xs:complexType> </xs:element> </xs:schema>
<!-- definition of attributes --> <xs:attribute name="orderid" type="xs:string"/> <!-- definition of complex elements --> <xs:element name="shipto"> <xs:complexType> <xs:sequence> <xs:element ref="name"/> <xs:element ref="address"/> <xs:element ref="city"/> <xs:element ref="country"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="item"> <xs:complexType> <xs:sequence> <xs:element ref="title"/> <xs:element ref="note" minOccurs="0"/> <xs:element ref="quantity"/> <xs:element ref="price"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="shiporder"> <xs:complexType> <xs:sequence> <xs:element ref="orderperson"/> <xs:element ref="shipto"/> <xs:element ref="item" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute ref="orderid" use="required"/> </xs:complexType> </xs:element> </xs:schema>
The third design method defines classes or types, that enables us to reuse element definitions. This is done by naming the simpleTypes and complexTypes elements, and then point to them through the type attribute of the element. Here is the third design of the schema file ("shiporder.xsd"): <?xml version="1.0" encoding="ISO-8859-1" ?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:simpleType name="stringtype"> <xs:restriction base="xs:string"/> </xs:simpleType> <xs:simpleType name="inttype"> <xs:restriction base="xs:positiveInteger"/> </xs:simpleType> <xs:simpleType name="dectype"> <xs:restriction base="xs:decimal"/> </xs:simpleType> <xs:simpleType name="orderidtype"> <xs:restriction base="xs:string"> <xs:pattern value="[0-9]{6}"/> </xs:restriction> </xs:simpleType> <xs:complexType name="shiptotype"> <xs:sequence> <xs:element name="name" type="stringtype"/> <xs:element name="address" type="stringtype"/> <xs:element name="city" type="stringtype"/> <xs:element name="country" type="stringtype"/> </xs:sequence> </xs:complexType> <xs:complexType name="itemtype"> <xs:sequence> <xs:element name="title" type="stringtype"/> <xs:element name="note" type="stringtype" minOccurs="0"/> <xs:element name="quantity" type="inttype"/> <xs:element name="price" type="dectype"/> </xs:sequence> </xs:complexType> <xs:complexType name="shipordertype"> <xs:sequence> <xs:element name="orderperson" type="stringtype"/> <xs:element name="shipto" type="shiptotype"/>
<xs:element name="item" maxOccurs="unbounded" type="itemtype"/> </xs:sequence> <xs:attribute name="orderid" type="orderidtype" use="required"/> </xs:complexType> <xs:element name="shiporder" type="shipordertype"/> </xs:schema> The restriction element indicates that the datatype is derived from a W3C XML Schema namespace datatype. So, the following fragment means that the value of the element or attribute must be a string value: <xs:restriction base="xs:string"> The restriction element is more often used to apply restrictions to elements. Look at the following lines from the schema above: <xs:simpleType name="orderidtype"> <xs:restriction base="xs:string"> <xs:pattern value="[0-9]{6}"/> </xs:restriction> </xs:simpleType> This indicates that the value of the element or attribute must be a string, it must be exactly six characters in a row, and those characters must be a number from 0 to 9.
Note: The XML processor will not modify the value if you use the string data type.
Note: In the example above the XML processor will replace the tabs with spaces.
Note: In the example above the XML processor will remove the tabs.
ENTITIES ENTITY ID IDREF IDREFS language Name NCName NMTOKEN NMTOKENS normalizedString QName string token A string A string that does not contain line feeds, carriage returns, or tabs A string that represents the NMTOKEN attribute in XML (only used with schema A string that contains a valid language id A string that contains a valid XML name
A string that represents the ID attribute in XML (only used with schema attribute
A string that represents the IDREF attribute in XML (only used with schema attri
A string that does not contain line feeds, carriage returns, tabs, leading or trailin multiple spaces
Date and time data types are used for values that contain date and time.
Note: All components are required! The following is an example of a date declaration in a schema: <xs:element name="start" type="xs:date"/> An element in your document might look like this: <start>2002-09-24</start>
Time Zones
To specify a time zone, you can either enter a date in UTC time by adding a "Z" behind the date - like this: <start>2002-09-24Z</start> or you can specify an offset from the UTC time by adding a positive or negative time behind the date - like this: <start>2002-09-24-06:00</start> or
<start>2002-09-24+06:00</start>
Note: All components are required! The following is an example of a time declaration in a schema: <xs:element name="start" type="xs:time"/> An element in your document might look like this: <start>09:00:00</start> Or it might look like this: <start>09:30:10.5</start>
Time Zones
To specify a time zone, you can either enter a time in UTC time by adding a "Z" behind the time - like this: <start>09:30:10Z</start> or you can specify an offset from the UTC time by adding a positive or negative time behind the time - like this: <start>09:30:10-06:00</start> or <start>09:30:10+06:00</start>
Note: All components are required! The following is an example of a dateTime declaration in a schema: <xs:element name="startdate" type="xs:dateTime"/> An element in your document might look like this: <startdate>2002-05-30T09:00:00</startdate> Or it might look like this: <startdate>2002-05-30T09:30:10.5</startdate>
Time Zones
To specify a time zone, you can either enter a dateTime in UTC time by adding a "Z" behind the time - like this: <startdate>2002-05-30T09:30:10Z</startdate> or you can specify an offset from the UTC time by adding a positive or negative time behind the time - like this: <startdate>2002-05-30T09:30:10-06:00</startdate> or <startdate>2002-05-30T09:30:10+06:00</startdate>
The following is an example of a duration declaration in a schema: <xs:element name="period" type="xs:duration"/> An element in your document might look like this: <period>P5Y</period> The example above indicates a period of five years. Or it might look like this: <period>P5Y2M10D</period> The example above indicates a period of five years, two months, and 10 days. Or it might look like this: <period>P5Y2M10DT15H</period> The example above indicates a period of five years, two months, 10 days, and 15 hours. Or it might look like this: <period>PT15H</period> The example above indicates a period of 15 hours.
Negative Duration
To specify a negative duration, enter a minus sign before the P:
Defines a date value Defines a date and time value Defines a time interval Defines a part of a date - the day (DD) Defines a part of a date - the month (MM) Defines a part of a date - the month and day (MM-DD) Defines a part of a date - the year (YYYY) Defines a part of a date - the year and month (YYYY-MM) Defines a time value
<xs:element name="prize" type="xs:integer"/> An element in your document might look like this: <prize>999</prize> Or it might look like this: <prize>+999</prize> Or it might look like this: <prize>-999</prize> Or it might look like this: <prize>0</prize>
byte decimal int integer long negativeInteger nonNegativeInteger nonPositiveInteger positiveInteger short unsignedLong unsignedInt unsignedShort
A signed 8-bit integer A decimal value A signed 32-bit integer An integer value A signed 64-bit integer An integer containing only negative values (..,-2,-1) An integer containing only non-negative values (0,1,2,..) An integer containing only non-positive values (..,-2,-1,0) An integer containing only positive values (1,2,..) A signed 16-bit integer An unsigned 64-bit integer An unsigned 32-bit integer An unsigned 16-bit integer
unsignedByte
Binary data types are used to express binary-formatted data. We have two binary data types: base64Binary (Base64-encoded binary data) hexBinary (hexadecimal-encoded binary data)
XML Editors
Previous Next Chapter
If you are serious about XML, you will benefit from using a professional XML Editor.
XML is Text-based
XML is a text-based markup language. One great thing about XML is that XML files can be created and edited using a simple texteditor like Notepad. However, when you start working with XML, you will soon find that it is better to edit XML documents using a professional XML editor.
Today XML is an important technology, and development projects use XML-based technologies like: XML Schema to define XML structures and data types XSLT to transform XML data SOAP to exchange XML data between applications WSDL to describe web services RDF to describe web resources XPath and XQuery to access XML data SMIL to define graphics
To be able to write error-free XML documents, you will need an intelligent XML editor!
XML Editors
Professional XML editors will help you to write error-free XML documents, validate your XML against a DTD or a schema, and force you to stick to a valid XML structure. An XML editor should be able to: Add closing tags to your opening tags automatically Force you to write valid XML Verify your XML against a DTD Verify your XML against a Schema Color code your XML syntax
XSD Elements
Element Explanation
all
Specifies that the child elements can appear in any order. Each child element or 1 time Specifies the top-level element for schema comments
annotation
any
Enables the author to extend the XML document with elements not specified b schema Enables the author to extend the XML document with attributes not specified schema
Specifies information to be used by the application (must go inside annotation Defines an attribute Defines an attribute group to be used in complex type definitions
Allows only one of the elements contained in the <choice> declaration to be p within the containing element
complexContent
Defines extensions or restrictions on a complex type that contains mixed cont elements only Defines a complex type element Defines text comments in a schema (must go inside annotation) Defines an element Extends an existing simpleType or complexType element
Specifies an XPath expression that specifies the value used to define an identi Defines a group of elements to be used in complex type definitions Adds multiple schemas with different target namespace to a document Adds multiple schemas with the same target namespace to a document
Specifies an attribute or element value as a key (unique, non-nullable, and al present) within the containing element in an instance document
keyref
Specifies that an attribute or element value correspond to those of the specifi unique element
Defines a simple type element as a list of values Describes the format of non-XML data within an XML document
Redefines simple and complex types, groups, and attribute groups from an ex schema Defines restrictions on a simpleType, simpleContent, or a complexContent Defines the root element of a schema
Specifies that the child elements must appear in a sequence. Each child eleme from 0 to any number of times
simpleContent
Contains extensions or restrictions on a text-only complex type or on a simple content and contains no elements
simpleType
Defines a simple type and specifies the constraints and information about the attributes or text-only elements
union unique
Defines that an element or an attribute value must be unique within the scope
enumeration fractionDigits
Specifies the maximum number of decimal places allowed. Must be equal to o than zero
length
Specifies the exact number of characters or list items allowed. Must be equal than zero
maxExclusive maxInclusive
Specifies the upper bounds for numeric values (the value must be less than th
Specifies the upper bounds for numeric values (the value must be less than o this value)
maxLength
Specifies the maximum number of characters or list items allowed. Must be eq greater than zero
minExclusive minInclusive
Specifies the lower bounds for numeric values (the value must be greater tha
Specifies the lower bounds for numeric values (the value must be greater tha this value)
minLength
Specifies the minimum number of characters or list items allowed. Must be eq greater than zero Defines the exact sequence of characters that are acceptable Specifies the maximum number of digits allowed. Must be greater than zero
Specifies how white space (line feeds, tabs, spaces, and carriage returns) is h