Ten rozdział pokaże jak napisać schematu XML. Dowiesz się również, że schemat można zapisać na różne sposoby.
Dokument XML
Rzućmy okiem na ten dokument XML o nazwie "shiporder.xml" :
<?xml version="1.0" encoding="UTF-8"?>
<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>
Powyższy dokument XML składa się z elementu głównego "shiporder" , który zawiera żądany atrybut o nazwie "orderid" . "shiporder" element zawiera trzy różne elementy podrzędne: "orderperson" , "shipto" i "item" . "item" elementem pojawia się dwukrotnie, a zawiera on "title" , opcjonalnie "note" całość, "quantity" i "price" elementu.
Linia powyżej: xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" opowiada parsera XML, że dokument ten powinien zostać zatwierdzony przed schematu. Linia: xsi: noNamespaceSchemaLocation = "shiporder.xsd" określa, na którym znajduje się schematu (here it is in the same folder as "shiporder.xml") .
Tworzenie schematu XML
Teraz chcemy utworzyć schemat dla dokumentu XML powyżej.
Zaczynamy od otwarcia nowego pliku, który będziemy nazywać "shiporder.xsd" . Aby utworzyć schemat moglibyśmy po prostu śledzić strukturę dokumentu XML i definiują każdy element, jakim go znaleźć. Zaczniemy od standardowej deklaracji XML, a następnie przez xs: elementu schematu, który definiuje schematu:
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
</xs:schema>
W schemacie powyżej używamy standardowej przestrzeni nazw (xs) , a także związane z tym URI przestrzeni nazw jest definicja języka schematu, który ma standardową wartość http://www.w3.org/2001/XMLSchema.
Następnie musimy zdefiniować "shiporder" element. Ten element posiada atrybut i zawiera inne elementy, dlatego uważamy go jako typ złożony. Elementy podrzędne "shiporder" elementu jest otoczony xs: elementu sekwencji, który określa uporządkowaną sekwencję elementów podrzędnych:
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
...
</xs:sequence>
</xs:complexType>
</xs:element>
Następnie musimy zdefiniować "orderperson" element jako prostego typu (ponieważ nie zawierają żadnych atrybutów lub inne elementy). Pola typu (xs:string) jest poprzedzona przedrostkiem przestrzeni nazw związanej z XML Schema, który wskazuje predefiniowany typ danych schematu:
<xs:element name="orderperson" type="xs:string"/>
Następnie musimy zdefiniować dwa elementy, które są kompleksu typu: "shipto" i "item" . Zaczynamy od zdefiniowania "shipto" elementu:
<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>
Z schematów możemy określić liczbę możliwych zdarzeń dla elementu z maxOccurs i atrybuty minOccurs. maxOccurs określa maksymalną liczbę zdarzeń na element i minOccurs określa minimalną liczbę wystąpień dla elementu. Domyślną wartością dla obu maxOccurs i minOccurs jest jeden!
Teraz możemy zdefiniować "item" element. Ten element może pojawić się wiele razy wewnątrz "shiporder" elementu. To jest określona przez ustawienie maxOccurs atrybut "item" pierwiastka "unbounded" , co oznacza, że nie może być tak wiele wystąpień "item" elementu jako życzeniem autora. Zauważ, że "note" element jest opcjonalny. Mamy określić to poprzez ustawienie minOccurs przypisać do zera:
<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>
Teraz możemy zadeklarować atrybut "shiporder" elementu. Ponieważ jest to wymagane używanie atrybutu określamy = "required".
Note: Deklaracje atrybutów zawsze muszą pochodzić ostatnia:
<xs:attribute name="orderid" type="xs:string" use="required"/>
Oto pełna lista pliku schematu zwanego "shiporder.xsd" :
<?xml version="1.0" encoding="UTF-8" ?>
<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>
Podzielić schematu
Poprzednia metoda konstrukcja jest bardzo prosta, ale może być trudne do odczytania i utrzymania, gdy dokumenty są złożone.
Kolejna metoda projektowania opiera się na określeniu wszystkich elementów i atrybutów, a potem odwołując się do nich za pomocą ref atrybut.
Oto nowa konstrukcja pliku schematu ("shiporder.xsd") :
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- definition of simple elements -->
<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>
Korzystanie nazwanych typów
Trzecia metoda projektowania określa klas lub typów, które pozwala nam korzystać z definicji elementu. Odbywa się to poprzez nazwanie simpleTypes i complexTypes elementy, a następnie wskaż im przez type atrybutu elementu.
Oto trzecia konstrukcja pliku schematu ("shiporder.xsd") :
<?xml version="1.0" encoding="UTF-8" ?>
<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>
Element ograniczenie wskazuje, że typ danych pochodzi z W3C XML Schema przestrzeni nazw typu danych. Dlatego poniższy fragment oznacza, że wartość elementu lub atrybutu musi być ciąg znaków:
<xs:restriction base="xs:string">
Element ograniczenie jest coraz częściej używane do nakładania ograniczeń na elementy. Spójrz na następujących liniach ze schematu powyżej:
<xs:simpleType name="orderidtype">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{6}"/>
</xs:restriction>
</xs:simpleType>
Oznacza to, że wartość elementu lub atrybutu musi być ciągiem, to musi być dokładnie sześć znaków w wierszu, a te znaki muszą być liczbą od 0 do 9.