An XSD Instance
- 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 the 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 mandatory attribute named "orderid". The "shiporder" element contains three different child elements: "orderperson", "shipto", and "item". The "item" element appears twice, containing 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 and define 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 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 in 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 defined 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 can 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 "item" element's maxOccurs attribute to "unbounded", allowing the "item" element to appear any number of times as desired by the creator. 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 the 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 defining all elements and attributes first, and then using the ref attribute to refer to them.
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"> <!-- Definition of simple element --> <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 attribute --> <xs:attribute name="orderid" type="xs:string"/> <!-- Definition of composite element --> <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, which allows 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 schema file ("shiporder.xsd") is designed using the third method:
<?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 originates from the W3C XML Schema namespace. Therefore, the following fragment 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 0-9 digits.
- Previous Page XSD Element Substitution
- Next Page XSD String