An Example of XSD
- Previous Page XSD Element Substitution
- Next Page XSD String
This section will demonstrate how to write an XML Schema. You will also learn about different methods of writing schemas.
XML document
Let's take a look at this XML document named "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>George Bush</orderperson> <shipto> <name>John Adams</name> <address>Oxford Street</address> <city>London</city> <country>UK</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 above XML document includes the root element "shiporder", which contains a required attribute named "orderid". The "shiporder" element contains three different child elements: "orderperson", "shipto", and "item". The "item" element appears twice, it contains a "title", an optional "note" element, a "quantity", and a "price" element.
This line xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" informs the XML parser to validate the document according to a certain schema. This line: xsi:noNamespaceSchemaLocation="shiporder.xsd" specifies the location of the schema (which is in the same folder as "shiporder.xml").
Create an XML Schema
Now, we need to create a schema for the above XML document.
We can start by opening a new file and naming it "shiporder.xsd". To create a schema, we simply need to follow the structure of the XML document, defining each element we find. First, we start with a standard XML declaration:
<?xml version="1.0" encoding="ISO-8859-1" ?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> ... ... </xs:schema>
In the above schema, we use the standard namespace (xs), which is associated with the Schema language definition (Schema language definition), with the standard value of http://www.w3.org/2001/XMLSchema.
Next, we need to define the "shiporder" element. This element has an attribute that contains other elements, so we identify it as a complex type. The child elements of the "shiporder" element are enclosed by the xs:sequence element, defining the order of the child elements:
<xs:element name="shiporder"> <xs:complexType> <xs:sequence> ... ... </xs:sequence> ... </xs:complexType> </xs:element>
Then we need to define the "orderperson" element as a simple type (this is because it does not contain any attributes or other elements). The prefix of the type (xs:string) is specified by the namespace prefix, which is associated with the XML schema that indicates the pre-defined schema data types:
<xs:element name="orderperson" type="xs:string"/>
Next, I need to define two elements as complex types: "shipto" and "item". We start by defining the "shipto" element:
<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>
Through the schema, we can use the maxOccurs and minOccurs attributes to define the number of times an element may appear. maxOccurs defines the maximum number of times an element may appear, while minOccurs defines the minimum number of times an element must appear. The default values for maxOccurs and minOccurs are both 1!
Now, we can define the "item" element. This element can appear multiple times within the "shiporder" element. This is achieved by setting the value of the maxOccurs attribute of the "item" element to "unbounded", allowing the "item" element to appear as many times as the creator desires. Please note that the "note" element is an optional element. We have set the minOccurs attribute of this element to 0:
<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>
Now, we can declare the attributes of the "shiporder" element. Since this is a required attribute, we specify use="required".
Note:The declaration of this attribute must be placed at the end:
<xs:attribute name="orderid" type="xs:string" use="required"/>
This is the document list of this schema file named "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>
Splitting Schema
The previous design method is very easy, but it is difficult to read and maintain when the document is complex.
The design method introduced next is based on first defining all elements and attributes, and then referencing them using the ref attribute.
This schema file is designed using a new method:
<?xml version="1.0" encoding="ISO-8859-1" ?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!-- Easy element definition --> <xs:element name="orderperson" type="xs:string"/> <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:element name="title" type="xs:string"/> <xs:element name="note" type="xs:string"/> <xs:element name="quantity" type="xs:positiveInteger"/> <xs:element name="price" type="xs:decimal"/> <!-- 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>
Using specified types (Named Types)
The third design method defines classes or types, enabling us to reuse the definitions of elements. Specifically, it involves naming simple elements and complex elements first, and then pointing to them through the type attribute of the elements.
This is a schema file designed using the third method ("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 data type of the element comes from the W3C XML Schema namespace. Therefore, the following fragment also means that the value of the element or attribute must be a string type value:
<xs:restriction base="xs:string">
The restriction element is often used to impose restrictions on elements. Please see the following fragments from the above schema.
<xs:simpleType name="orderidtype"> <xs:restriction base="xs:string"> <xs:pattern value="[0-9]{6}"/> </xs:restriction> </xs:simpleType>
This code indicates that the value of the element or attribute must be a string and must be a continuous six-character string, and these characters must be numbers from 0 to 9.
- Previous Page XSD Element Substitution
- Next Page XSD String