'n XSD- voorbeeld
Hierdie hoofstuk sal demonstreer hoe om 'n XML-skema te skryf. Jy sal ook leer dat 'n skema op verskillende maniere geskryf kan word.
'n XML-dokument
Kom ons kyk na hierdie XML-dokument genaamd "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>
Die XML-dokument hierbo bestaan uit 'n wortelelement, "shiporder", wat 'n vereiste kenmerk genaamd "orderid" bevat. Die "shiporder"-element bevat drie verskillende kinderelemente: "orderperson", "shipto" en "item". Die "item"-element verskyn twee keer, en dit bevat 'n "titel", 'n opsionele "noot"-element, 'n "hoeveelheid" en 'n "prys"-element.
Die reël hierbo: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" vertel die XML-ontleder dat hierdie dokument teen 'n skema bekragtig moet word. Die reël: xsi:noNamespaceSchemaLocation="shiporder.xsd" spesifiseer WAAR die skema is (hier is dit in dieselfde vouer as "shiporder.xml").
Skep 'n XML-skema
Nou wil ons 'n skema vir die XML-dokument hierbo skep.
Ons begin deur 'n nuwe lêer oop te maak wat ons "shiporder.xsd" sal noem. Om die skema te skep, kan ons eenvoudig die struktuur in die XML-dokument volg en elke element definieer soos ons dit vind. Ons sal begin met die standaard XML-verklaring gevolg deur die xs:skema-element wat 'n skema definieer:
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
</xs:schema>
In die skema hierbo gebruik ons die standaard naamruimte (xs), en die URI wat met hierdie naamruimte geassosieer word, is die Skema-taaldefinisie, wat die standaardwaarde van http://www.w3.org/2001/XMLSchema het.
Vervolgens moet ons die "shiporder"-element definieer. Hierdie element het 'n eienskap en dit bevat ander elemente, daarom beskou ons dit as 'n komplekse tipe. Die kind-elemente van die "shiporder"-element word omring deur 'n xs:sekwensie-element wat 'n geordende reeks sub-elemente definieer:
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
...
</xs:sequence>
</xs:complexType>
</xs:element>
Dan moet ons die "orderperson"-element as 'n eenvoudige tipe definieer (omdat dit geen kenmerke of ander elemente bevat nie). Die tipe (xs:string) word voorafgegaan met die naamruimtevoorvoegsel wat met XML-skema geassosieer word wat 'n voorafbepaalde skemadatatipe aandui:
<xs:element name="orderperson" type="xs:string"/>
Vervolgens moet ons twee elemente definieer wat van die komplekse tipe is: "shipto" en "item". Ons begin deur die "shipto"-element te definieer:
<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>
Met skemas kan ons die aantal moontlike voorkomste vir 'n element met die maxOccurs- en minOccurs-kenmerke definieer. maxOccurs spesifiseer die maksimum aantal voorkomste vir 'n element en minOccurs spesifiseer die minimum aantal voorkomste vir 'n element. Die verstekwaarde vir beide maxOccurs en minOccurs is 1!
Nou kan ons die "item" element definieer. Hierdie element kan verskeie kere in 'n "shiporder"-element verskyn. Dit word gespesifiseer deur die maxOccurs-kenmerk van die "item"-element op "unbounded" te stel, wat beteken dat daar soveel voorkoms van die "item"-element kan wees as wat die skrywer wil hê. Let daarop dat die "noot"-element opsioneel is. Ons het dit gespesifiseer deur die minOccurs-kenmerk op nul te stel:
<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>
Ons kan nou die kenmerk van die "shiporder"-element verklaar. Aangesien dit 'n vereiste kenmerk is, spesifiseer ons use="required".
Let wel: Die kenmerkverklarings moet altyd laaste kom:
<xs:attribute name="orderid" type="xs:string" use="required"/>
Hier is die volledige lys van die skemalêer genaamd "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>
Verdeel die Skema
Die vorige ontwerpmetode is baie eenvoudig, maar kan moeilik wees om te lees en in stand te hou wanneer dokumente kompleks is.
Die volgende ontwerpmetode is daarop gebaseer om alle elemente en eienskappe eers te definieer, en dan daarna te verwys deur die ref-kenmerk te gebruik.
Hier is die nuwe ontwerp van die skemalêer ("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>
Gebruik benoemde tipes
Die derde ontwerpmetode definieer klasse of tipes, wat ons in staat stel om elementdefinisies te hergebruik. Dit word gedoen deur die simpleTypes- en complexTypes-elemente te noem, en dan na hulle te wys deur die tipe-kenmerk van die element.
Hier is die derde ontwerp van die skemalêer ("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>
Die beperkingselement dui aan dat die datatipe afgelei is van 'n W3C XML Skema naamruimte datatipe. Dus, die volgende fragment beteken dat die waarde van die element of kenmerk 'n stringwaarde moet wees:
<xs:restriction base="xs:string">
Die beperkingselement word meer dikwels gebruik om beperkings op elemente toe te pas. Kyk na die volgende reëls uit die skema hierbo:
<xs:simpleType name="orderidtype">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{6}"/>
</xs:restriction>
</xs:simpleType>
Dit dui aan dat die waarde van die element of kenmerk 'n string moet wees, dit moet presies ses karakters in 'n ry wees, en daardie karakters moet 'n getal van 0 tot 9 wees.