XML Schema

Mihai Gabroveanu

Abstract

O XML Schema este un document bine format (de regula cu extensia .xsd) care defineste structura si tipul elementelor unui document XML in vederea valiadarii.


1. Introducere
2. XML Schema
2.1. Referirea la o XML Schema
2.2. Definirea unui fisier XML Schema
2.3. Tipuri simple
2.4. Definirea unui element simplu
2.5. Definirea atributelor
2.6. Definirea restrictiilor/fatetelor
2.6.1. Restrictii pentru numere
2.6.2. Restrictii pentru stringuri
2.6.3. Restrictii pe o multime de valori
2.7. Definirea elementelor complexe
2.7.1. Definirea elementelor vide
2.7.2. Definitii globale si locale
2.7.3. Utilizarea tipurilor declarate
2.7.4. Extinderea unui tip
2.8. Indicatori de ordine
2.8.1. Indicatorul de secventa xs:sequence
2.8.2. Indicatorul all xs:all
2.8.3. Indicatorul de alegere xs:choice
2.9. Indicatori de aparitie
2.9.1. Indicatorul maxOccurs
2.9.2. Indicatorul minOccurs
2.10. Indicatorii de grupare
2.10.1. Indicatori de grupare a elementelor
2.10.2. Indicatori de grupare a atributelor
3. Exemplu
3.1. Divizarea schemei
3.2. Asignarea de nume tipurilor
4. Bibliografie

1. Introducere

XML Schema a inceput ca o initiativa a companiei Microsoft. Intre timp insa, consortiul W3C a preluat aceasta initiativa si a dezvoltat un set mai larg de cerinte si caracteristici pentru documente ce descriu tipuri de documente. Acestea sunt reunite sub numele de Document Content Description, informatii despre acest proiect sunt disponibile la http://www.w3.org/TR/NOTE-dcd. In anul 2001 propunerea a devenit recomandare a W3C. Spre deosebire de (sau in plus fata de) DTD-uri, XML schema permite definirea regulilor si relatiilor intre elemente si attribute folosind un fisier XML (cu alte cuvinte, o schema XML este descrisa intr-un fisier XML). In plus, se adauga suport pentru spatii de nume (namespaces), tipuri de date si caracteristici mai avansate cum ar fi constrangerile (constraints).

2. XML Schema

O XML Schema:

  • defineste elementele care pot sa apara intr-un document

  • defineste atributele pe care pot sa le aiba elementele dintr-un document

  • defineste care elemente au copii si care sunt acestia

  • defineste ordinea copiilor unui element

  • defineste numarul de copii

  • defineste daca un element este vid sau poate contine un text

  • defineste tipurile elementelor si atributelor

  • defineste valorile implicite si fixe ale elementelor si atributelor

2.1. Referirea la o XML Schema

Spre deosebire de referirea la un DTD intr-un document XML care se facea inainte de elementul radacina:

<?xml version="1.0?>
<!DOCTYPE elementRadacina SYSTEM "url">
<elementRadacina> 
  ... 
</elementRadacina>

Referirea la o XML Schema intr-un document XML se face in cadrul elementului radacina:

<?xml version="1.0"?>
<elementRadacina  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"1 
                  xsi:noNamespaceSchemaLocation="url.xsd"2>
      ...
</elementRadacina>

unde:

1

Referirea la instanta de de schema XML utilizata

2

Locatia unde poate fi gasita definitia schemei

Exemplu:

<?xml version="1.0">
<CARTE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="CARTE.xsd" >
    <TITLU>XML Bible</TITLU>
    <AUTOR>Elliotte Rusty Harold</AUTOR>
    <EDITURA> IDG Books Worldwide</EDITURA>
    <AN_APARITIE>2002</AN_APARITIE>
</CARTE>  

2.2. Definirea unui fisier XML Schema

Un fisier XML Schema utilizeaza sintaxa XML pentru definirea structurii si tipurilor elementelor unui document XML in vederea validarii. Un fisier XML Schema are extensia .xsd si este un fisier XML ce are ca radacina <schema>. Forma generala a unui astfel de document este urmatoarea:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"1 targetNamespace="http://inf.ucv.ro" 2
        xmlns="http://inf.ucv.ro" 3elementFormDefault="qualified"4>
...
...
</xs:schema>      

unde:

1

indica faptul ca elementele si tipurile de date utilizate in schema (schema, element, complexType, sequence, string, boolean, etc.) provin din namespace-ul "http://www.w3.org/2001/XMLSchema". De asemenea specifica ca aceste elemente si tipuri de date ce provin din namespace-ul "http://www.w3.org/2001/XMLSchema" trebuie sa fie prefixate cu xs:

2

indica faptul ca elementele din definita prin aceasta schema provin din namespace-ul "http://inf.ucv.ro"

3

indica namespace-ul implicit

4

indica ca toate elemente XML utilizate trebuie sa fie calificate de namespace.

Exemplu:

2.3. Tipuri simple

Un element se numeste element simplu daca:

  • contine numai informatie text (date caracter)

  • nu are atribute

  • nu contine alte atribute

  • nu este vid

Totusi informatia text continuta de element poate sa fie de diferite tipuri. Ea poate sa fie de unul dintre tipurile predefinite in XML Schema (boolean, string, date, etc.), sau poate fi de un tip definit de noi. De asemenea se pot adauga restricii (fatete) asupra tipurilor de date pentru a stabili limitele, sau putem sa stabilim un patern peste care trebuie sa se potriveasca.

2.4. Definirea unui element simplu

Sintaxa definiri unui element simplu este urmatoarea:

<xs:element name="nume" type="tip"/>

unde:

  • nume este numele elementului

  • tip este tipul elementului

In XML Schema sunt predefinite urmatoarele tipuri:

  • xs:string

  • xs:decimal

  • xs:integer

  • xs:boolean

  • xs:date

  • xs:time

Exemplu: sa consideram urmatoarele elemente XML:

 <NUME>Popescu Maria</NUME>
 <VARSTA>21</VARSTA>
 <DATA_NASTERII>1985-09-23</DATA_NASTERII>

atunci definitiile corespunzatoare ale acestor elemente simple in XML Schema sunt:

<xs:element name="NUME" type="xs:string"/>
<xs:element name="VARSTA" type="xs:integer"/>
<xs:element name="DATA_NASTERII" type="xs:date"/> 

Elementele simple pot avea in anumite situatii valori implicite SAU o valore fixa. Sintaxa declararii acestora este:

<xs:element name="nume" type="tip" default="valoare-implicita"/>

si respectiv:

<xs:element name="nume" type="tip" fixed="valoare-fixa"/>

O valoare implicita este atribuita unui element atunci cand nu este specificata nici o alta valoare valoare. In exemplul urmator valoarea implicita este "alb-negru":

<xs:element name="TIP-IMPRIMANTA" type="xs:string" default="alb-negru"/>

O valoare fixa este atribuita de asemenea automat unui element si nu putem specifica nici o alta valoare in afara de cea specificata. In exemplul urmator valoarea fixa este "romana":

<xs:element name="CETATENIA" type="xs:string" fixed="romana"/>

2.5. Definirea atributelor

Elementele simple nu pot avea atribute. Daca un element are cel putin un atribut atunci este considerat de element de tip complex. Totusi, atributul insusi este declarat intotdeauna ca un tip simplu. Sintaxa de definire a unui atribut este urmatoarea:

<xs:attribute name="nume" type="tip" />

unde:

  • nume este numele atributului

  • tip este tipul atributului identic cu cel de la definirea elementelor simple

Exemplu: daca cosideram urmatorul element cu un atribut:

<PERSOANA sex="masculin">Garcea Ion</PERSOANA>  

atunci definitia atributului cnp este urmatoarea:

<xs:attribute name="sex" type="xs:string"/>

Sintaxa XML Schema pentru definirea atributelor permite de asemenea definirea de valori implicite (default) pentru atribute SAU atribute cu valori fixe. Sintaxa definirii acestora este urmatoarea:

<xs:attribute name="nume" type="tip" default="valoare-implicita" />

si respectiv:

<xs:attribute name="nume" type="tip" fixed="valoare-fixa" />

De asemenea sintaxa permite stabilirea faptului ca atributul este optional sau obligatoriu. Sintaxa definirii acestora este urmatoarea:

<xs:attribute name="nume" type="tip" use="optional" />

si respectiv:

<xs:attribute name="nume" type="tip" use="required" />

2.6. Definirea restrictiilor/fatetelor

Atunci cand definim tipul pentru un element simplu sau pentru un atribut, automat sunt impuse asupa continutului o serie de conditii. Astfel daca pentru un element am stabilit tipul xs:integer si contine o valoare de genul "21-07-2006" documentul respectiv nu va fi valid. Avem posibilitatea sa definim si alte restrictii proprii asupa continutului elementului sau atributului. Aceste restrictii se numesc fatete.

Sintaxa generala a definirii acestor restrictii este urmatoarea:

<xs:element name="nume">               (sau xs:attribute) 
 <xs:simpleType>
    <xs:restriction base="tip">     
      ... restrictii ... 
   </xs:restriction>
 </xs:simpleType>
</xs:element>

Exemplu:

<xs:element name="nota">
<xs:simpleType>
   <xs:restriction base="xs:integer">  
              <xs:minInclusive value="1">
              <xs:maxInclusive value="10">
   </xs:restriction>
</xs:simpleType>
</xs:element>

2.6.1. Restrictii pentru numere

Asupra valorilor de tip numeric putem definii urmatoarele tipuri de restrictii:

  • minInclusive - numarul trebuie sa fie mai mare sau egal decat o valoare data

  • minExclusive - numarul trebuie sa fie mai mare strict decat o valoare data

  • maxInclusive - numarul trebuie sa fie mai mic sau egal decat o valoare data

  • maxExclusive - numarul trebuie sa fie mai mic strict decat o valoare data

  • totalDigits - numarul de cifre ale numarului trebuie sa aiba exact o valoare data

  • fractionDigits - numarul de cifre de dupa virgula nu trebuie sa depaseasca o valoare data

2.6.2. Restrictii pentru stringuri

Asupra valorilor de tip string putem definii urmatoarele tipuri de restrictii:

  • length - lungimea sirului trebuie sa fie egala cu o valoare data

  • minLength - lungimea sirului trebuie sa fie mai mare sau egala cu o valoare data

  • maxLength - lungimea sirului trebuie sa fie mai mica sau egala cu o valoare data

  • pattern - sirul trebuie sa se potriveasca cu e expresie regulata data

  • whiteSpace - nu este chiar o restrictie, ea spune cum sa trateze spatiile albe (white spaces):

    • value="preserve" - se pastreaza toate spatiile albe

    • value="replace" - toate spatiile albe sunt inlocuite cu spatii

    • value="collapse" - toate spatiile albe sunt comasate la un singur spatiu

Exemplu: Daca presupunem ca elementul INITIALE este format din exact 3 caractere toate litere mari atunci definirea elementului este urmatoarea:

<xs:element name="INITIALE">
<xs:simpleType>
  <xs:restriction base="xs:string">
    <xs:pattern value="[A-Z][A-Z][A-Z]"/>
  </xs:restriction>
</xs:simpleType>
</xs:element> 

2.6.3. Restrictii pe o multime de valori

Putem impune ca valoarea unui element sau atribut sa ia numai o multime de valori. De exemplu daca consideram ca elementul ANOTIMP poate lua ca valori numai: primavara, vara, toamna si iarna atunci definitia elementului este urmatoarea:

<xs:element name="ANOTIMP">
 <xs:simpleType>
  <xs:restriction base="xs:string">
                 <xs:enumeration value="primavara"/>
                 <xs:enumeration value="vara"/>
                 <xs:enumeration value="toamna"/>
                 <xs:enumeration value="iarna"/>
   </xs:restriction>
  </xs:simpleType>
</xs:element>

2.7. Definirea elementelor complexe

Un element se numeste element complex daca contine alte element si/sau atribute. De asemenea elementele vide sunt considerate elemente complexe. Sintaxa definirii unui element complex este urmatoarea:

<xs:element name="nume">
        <xs:complexType> 
            ... descrierea tipului complex ...
        </xs:complexType>
</xs:element>

Exemplu:

<xs:element name="PERSOANA">
      <xs:complexType>
           <xs:sequence>
                <xs:element name="NUME" type="xs:string"/>
                <xs:element name="PRENUME" type="xs:string"/>
           </xs:sequence>
      </xs:complexType>
</xs:element>

<xs:sequence> spune ca elementele NUME si PRENUME trebuie sa apara in acesta ordine.

2.7.1. Definirea elementelor vide

Paradoxal elementele vide sunt de tip complex.

Sa consideram urmatorul element:

<PRODUS cod="1345" />

Definirea schemei pentru acesta arata astfel:

<xs:element name="PRODUS">
  <xs:complexType>
    <xs:complexContent>
      <xs:restriction base="xs:integer">
        <xs:attribute name="cod" type="xs:positiveInteger"/>
      </xs:restriction>
    </xs:complexContent>
  </xs:complexType>
</xs:element>

In exemplul anterior, am definit un complexType avand complexContent, adica numai elemente. Elementul complexContent semnaleaza ca intentionam sa restrictionam sau sa extindem un tip complex. Restrictia defineste un atribut cod ce poate lua numai valori pozitive.

Putem sa definim schema si astfel:

<xs:element name="PRODUS">
  <xs:complexType>
    <xs:attribute name="cod" type="xs:positiveInteger"/>
  </xs:complexType>
</xs:element>

2.7.2. Definitii globale si locale

Elementele declarate la nivele superioare ale unei <schema> sunt disponibile pentru restul schemei. Elementele declarate intr-un xs:complexType sunt locale in acel tip si nu pot fi referite la un nivel superior. Astfel in exemplul anterior elementele NUME si PRENUME sunt locale in cadrul elementului PERSOANA.

2.7.3. Utilizarea tipurilor declarate

Unui tip complex ii putem asigna un nume astfel:

<xs:complexType name="nume-tip">
          ....
</xs:complexType>

Apoi ne putem referii la el printr-o constructie de foma:

<xs:element name="nume" type="nume-tip-declarat"/>

Exemplu:

<xs:complexType name="PERSOANA">
           <xs:sequence>
                <xs:element name="NUME" type="xs:string"/>
                <xs:element name="PRENUME" type="xs:string"/>
           </xs:sequence>
</xs:complexType>
<xs:element name="STUDENT" type="PERSOANA"/>
<xs:element name="PROFESOR" type="PERSOANA"/>

Warning

Nu putem utiliza o referinta la un tip daca el este local unui alt tip!

2.7.4. Extinderea unui tip

Putem construi un tip complex prin extinderea unui alt tip complex:

<xs:complexType  name="tip-nou">   
  <xs:complexContent>  
        <xs:extension  base="alt-tip">
               ... caracteristici noi...
        </xs:extension>
     </xs:complexContent>
</xs:complexType>

2.8. Indicatori de ordine

Indicatori de oridine sunt utilizati pentru a defini ce elementele pot sa apara si in ce ordine.

2.8.1. Indicatorul de secventa xs:sequence

Am vazut deja cum se declara in cadrul unui tip complex elementele ce trebuie sa apara intr-o anumita ordine:

<xs:element name="PERSOANA">
      <xs:complexType>
           <xs:sequence>
                <xs:element name="NUME" type="xs:string"/>
                <xs:element name="PRENUME" type="xs:string"/>
           </xs:sequence>
      </xs:complexType>
</xs:element>

2.8.2. Indicatorul all xs:all

Pentru a declara o multimea de elemente ce trebuie sa apara intr-un tip complex in care ordinea nu conteaza vom utiliza constructia xs:all:

Exemplu: Daca elementele NUME si PRENUME trebuie sa apara in elementul PERSOANA insa ordinea nu conteaza, atunci avem:

<xs:element name="PERSOANA">
      <xs:complexType>
           <xs:all>
                <xs:element name="NUME" type="xs:string"/>
                <xs:element name="PRENUME" type="xs:string"/>
           </xs:all>
      </xs:complexType>
</xs:element>

2.8.3. Indicatorul de alegere xs:choice

Indicatorul xs:choice permite definirea de tipuri complexe in care unul din elementele dintr-o multime poate sa apara:

<xs:element name="CARTE">
      <xs:complexType>
           <xs:choice>
                <xs:element name="AUTOR" type="persoana"/>
                <xs:element name="EDITOR" type="persoana"/>
           </xs:choice>
      </xs:complexType>
</xs:element>

2.9. Indicatori de aparitie

Indicatorii de aparitie sunt utilizati pentru a defini de cate ori poate sa apara un element.

2.9.1. Indicatorul maxOccurs

Indicator maxOccurs specifica numarul maxim de aparitii pentru un element:

<xs:element name="PERSOANA">
      <xs:complexType>
           <xs:sequence>
                <xs:element name="NUME" type="xs:string"/>
                <xs:element name="NUME-COPIL" type="xs:string" maxOccurs="5"/>
           </xs:sequence>
      </xs:complexType>
</xs:element>

In exemplu anterior elementul NUME-COPIL trebuie sa apara cel putin odata (valoarea implicita pentru minOccurs este 1 implicit) si de maxim 5 ori in secventa ce descrie elementul PERSOANA.

2.9.2. Indicatorul minOccurs

Indicator minOccurs specifica numarul minim de aparitii pentru un element:

<xs:element name="PERSOANA">
    <xs:complexType>
         <xs:sequence>
            <xs:element name="NUME" type="xs:string"/>
            <xs:element name="NUME-COPIL" type="xs:string" minOccurs="0" maxOccurs="5"/>
         </xs:sequence> 
    </xs:complexType>
</xs:element>

In exemplu anterior elementul NUME-COPIL poate sa nu apara deloc sau de maxim 5 ori in secventa ce descrie elementul PERSOANA.

Note

Pentru toate tipurile de indicatori de grupare sau ordine (any, all, choice, sequence, group name, and group reference) valoarea implicita pentru maxOccurs and minOccurs este 1!

2.10. Indicatorii de grupare

2.10.1. Indicatori de grupare a elementelor

Sunt utilizati pentru multimi de elemente inrudite. Sintaxa definirii grupurilor de elemente este urmatoarea:

<xs:group name="nume-grup">
            ...
</xs:group>

in cadrul unui grup putem defini elemente all, choice, or sequence.

Exemplu: Sa presupunem ca dorim sa definim un grup cu nume "GRUP-PERSOANA", ce defineste grupul de elemente ce trebuie sa apara exact intr-o ordine specificata. Atunci avem:

<xs:group name="GRUP-PERSOANA">
       <xs:sequence>
            <xs:element name="NUME" type="xs:string"/>
            <xs:element name="PRENUME" type="xs:string"/>
            <xs:element name="DATA-NASTERE" type="xs:date"/>
        </xs:sequence>
</xs:group>

Ulterior ne putem referi la acel grup in cadrul altui grup sau in cadrul definirii tip complex astfel:

<xs:element name="PERSOANA" type="INFO-PERSOANA"/>
         
<xs:complexType name="INFO-PERSOANA">
       <xs:sequence>
            <xs:group ref="GRUP-PERSOANA"/>
            <xs:element name="TARA" type="xs:string"/>
       </xs:sequence>
</xs:complexType>

2.10.2. Indicatori de grupare a atributelor

Sintaxa definirii grupurilor de atribute este urmatoarea:

<xs:attributeGroup name="nume-grup">
            ...
</xs:attributeGroup>

Exemplu: Sa presupunem ca dorim sa definim un grup cu nume "GRUP-PERSOANA", ce defineste grupul de elemente ce trebuie sa apara exact intr-o ordine specificata. Atunci avem:

<xs:attributeGroup name="GRUP-PERSOANA">
            <xs:attribute name="nume" type="xs:string"/>
            <xs:attribute name="prenume" type="xs:string"/>
            <xs:attribute name="data-nasterii" type="xs:date"/>
</xs:attributeGroup>

Ulterior ne putem referi la acel grup in cadrul altui grup sau in cadrul definirii tip complex astfel:

<xs:element name="PERSOANA" type="INFO-PERSOANA"/>
            
<xs:complexType name="INFO-PERSOANA">
   <xs:attributeGroup ref="GRUP-PERSOANA">
</xs:complexType>

3. Exemplu

Sa consideram urmatorul document XML ce isi propune sa reprezinte un ordin de plata:

<?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>
          

O schema XML atasata acestui document ar putea arata astfel:

<?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>      

3.1. Divizarea schemei

Schema prezentata anterior este relativ simpla insa poate sa devina dificil de inteles in conditiile in care documentul ar fi mai complex.

In continuare este prezentata o versiune imbunatatita bazata pe urmatorul principiu: definim mai intai elemente si atributele, apoi le referim utilizand atributul ref.

<?xml version="1.0" encoding="ISO-8859-1" ?>
<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>

3.2. Asignarea de nume tipurilor

Putem sa rafinam si mai mult designul schemei asignand nume tipurilor:

<?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>

4. Bibliografie