Skeemid
Kui andmestik on lihtne ja alati samade tunnustega, siis on hea ette võtta sobiv
näide, omad andmed asemele panna ning saabki uusi andmeid olemasoleval kohal
kasutada. Kui aga on vaja täpsemalt teada, mis kuhu lubatud on, siis selle
kirjapanekuks on välja mõeldud skeemid. Seal määratakse, millise nimega
elemendid millises järjekorras on lubatud ning millist tüüpi ja millises
vahemikus andmeid võib kusagil kasutada. Skeemi järgi saab andmefaili
automaatselt kontrollida ning selle kaudu vähemasti märgatava osa näpuvigu
avastada. Vigade avastamine võimalikult varakult aitab vältida nende mõju
kasvamist. Samuti on skeemi pealt hea vaadata rakenduste loojatel, et kuidas
andmeid esitada tuleb. Mis on lubatud ja mis mitte.
Tutvuda tasub alates kõige lihtsamast võimalusest. XML-dokument, kus on vaid ühe
teate tekst.
Uus aasta algab 1. jaanuaril.
Et seal saab olla vaid üks tekstiline teade ja ei midagi muud, see tuleb
skeemina kirja panna järgnevalt.
Kuna skeem ise vastab XML-i reeglitele, siis peab tal ülal olema
tüübideklaratsioon.
Edasi teatatakse, et algab skeem.
Sealt siis teated, et millise nime ja millise tüübiga elemendid tulevad. Praegu
ainult üks element nimega teade ja sisutüübiks string.
Ja nagu XMLi puhul ikka, siis alanud element tuleb lõpetada.
Andmete vastavust skeemile saab kontrollida mitmetes programmeerimiskeeltes.
Järgnevalt näide Java kohta. Kõigepealt luuakse vastavalt skeemifailile
validaator ning edasi kontrollitakse selle järgi soovitud faili.
import javax.xml.validation.*;
import javax.xml.XMLConstants;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;
public class SkeemiKontroll{
public static void main(String[] argumendid) throws Exception{
if(argumendid.length!=2){
System.out.println("Kasuta kujul: java SkeemiKontroll skeem.xsd
andmefail.xml");
System.exit(0);
}
Validator
validaator=SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema").
newSchema(new
StreamSource(argumendid[0])).newValidator();
validaator.validate(new StreamSource(argumendid[1]));
}
}
Nagu ikka, tuleb enne käivitamist fail kompileerida. Ning edasi tuleb talle ette
anda skeem ning andmefail.
c:\temp>javac SkeemiKontroll.java
c:\temp>java SkeemiKontroll teade.xsd teade.xml
Skeemifaili asukoht on võimalik ka andmefaili enese sisse kirjutada. Järgnevas
näites märgitakse, et andmetele vastava skeemi leiab failist nimega
teateskeem.xsd . Kui failid avada nt Microsoft Visual Studio abil ja nad asuvad
samas kataloogis, siis kontrollitakse automaatselt, kas andmefail vastab
skeemile. Kui kõik on korras, siis ei teatata midagi.
Uus aasta algab 1. jaanuaril.
Kui aga andmefail ei peaks skeemile vastama, siis antakse vastav hoiatus. Siin
on teate sisse lisatud skeemis kirjeldamata element nimega "selgitus". Visual
Studio keskkond tõmbab sellele hoiatusjoone alla. Mõnes muus kohas aga näiteks
teatatakse käsureaaknast, et millisel koodireal ja milline viga leiti.
Uus aasta algab 1. jaanuaril.
Mitmest elemendist koosnev skeem.
Harva piirdub XML-fail ühe elemendiga. Ning õigupoolest pole nii lihtsa faili
tarbeks põhjust ka skeemi koostada. Kui elemente rohkem, siis aga skeem
kindlasti omal kohal. Järgnev kirjeldus inimese andmete kohta. Väliseks
elemendiks inimene. Et tema sisse saab teisi elemente paigutada, siis
määratakse, et tegemist on complexType'ga. Ning siin näites paiknevad sisemised
elemendid kindlas järjekorras jadana (sequence). Kõigepealt eesnimi stringi ehk
tekstina, siis perenimi ning lõpuks synniaasta. Viimane peab olema täisarvuline,
et andmestik validaatorist läbi läheks.
Skeemile vastav näide siis järgmine.
Juku
Juurikas
1989
Kui tahta, et suudetaks ka automaatselt kontrollida andmete vastavust skeemile,
siis tuleb skeemifaili asukoht juurelemendi atribuudi juures ära määrata.
Juku
Juurikas
1989
Ülesandeid
* Koosta skeem auto registrinumbri hoidmiseks.
* Loo vastav andmefail. Testi andmefaili vastavust skeemile.
* Koosta skeem, kus auto kohta on kirjas registrinumber, mark ja
väljalaskeaasta.
* Testi andmestiku vastavust skeemile.
Elemendi esinemise kordade arv
Eelmises näites on iga element ühekordselt. Kui midagi eraldi määratud pole,
siis käibki nõnda. Ehk siis vaikimisi on elemendi juurde kuuluvate
arvuatribuutide maxOccurs ning minOccurs väärtusteks 1. Need aga võib üle
kirjutada. Lubades kuni kolm eesnime, võib lisada atribuudi maxOccurs="3".
Nõnda muutub lubatavaks järgmine andmestik, kus inimesel kaks eesnime.
Juku
Ferdinant
Juurikas
1989
Kui element võib kord olla, kord puududa, siis tuleb kirjelduse juurde määrata
minOccurs="0". Sellistes kohtades on skeemist eriti kasu, sest näitfailis ei
pruugi vajalikku elementi olla, skeemist aga saab vaadata, mis on lubatud, mis
mitte.
Ning siis juurde näitena hüüdnimega andmestik.
Juku
juks
Juurikas
1989
Atribuudi kirjeldus tuleb samuti xs:complexType elemendi sisse panna. Mitte aga
elementide jadasse, vaid eraldi. Atribuutide puhul pole nende järjekord tähtis.
Atribuudiga element näeb siis välja järgmine.
Juku
Juurikas
1989
Ülesandeid
* Loo skeem auto kohta, millel võib lisaks omanikule olla kuni kolm kasutajat.
* Auto kütuse liik tähistatakse atribuudina.
Tüüpide täiendamine
Harilikuks tekstitüübiks on string, täisarvuks integer, murdarvuks decimal ning
kuupäevaks date. Kusjuures kuupäeva puhul tuleb andmed kirjutada alati kujul
aasta-kuu-päev. Hiljem rakenduses võib neid kasutajale sobival kujul sättida,
kuid XMLi standardis on määratud nõnda, et ei tekiks segadusi.
Juku
Juurikas
1989-11-05
Lihtsad andmed saab "kohe ja kohapeal" ära kirjeldada. Kui aga andmestik läheb
keerulisemaks, siis on võimalik üksikud osad enne gruppidena valmis teha ning
alles seejärel gruppe omavahel kombineerima hakata. Nii nagu programmikoodi
kirjutamisel saab enne valmis teha alamprogrammid ning neid siis sobivalt välja
kutsuma hakata, nii ka skeemi puhul on võimalik kõigepealt defineerida omaette
tüübid ning neid siis hiljem kasutada. Siinses lihtsas näites on kõigepealt
defineeritud isikutüüp ning hiljem märgitud, et dokument koosneb ühest,
isikutüüpi inimesest.
Juku
Juurikas
1989-11-05
Kui xs:sequence määras, et elemendid peavad olema kindlas järjekorras, siis
xs:all järjekorda ei määra, küll ütleb aga ikka, et kõik määratud elemendid
peavad olemas olema.
Nõnda on lubatud ja järgnev
Juurikas
1989
Juku
Käsklus xs:choice teatab, et määratutest peab olema ainult üks. Ehk siis
järgnevas näites saab inimese alla panna kooli või asutuse, aga mitte mõlemat.
Nurgametsa kool
Ülesandeid
* Koosta skeem auto andmete hoidmiseks. Märgi auto registreerimise aeg
kuupäevana. Kontrolli skeemi ja andmete sobivust.
* Luba auto andmed esitada vabas järjestuses.
* Defineeri isikuandmed (eesnimi, perekonnanimi, isikukood) eraldi tüübina.
Määra nii auto omanik kui kasutajad vastavat tüüpi.
* Valikuna on auto kütuseks kas bensiin, diisel või gaas. Bensiini puhul on
alamelementideks lubatud vähim ja suurim oktaanarv.
Tüüpide piirangud
Terviktüüpe ette võttes on kasutada string, date, integer ja decimal.
Tüübi juures lubatud terve väärtuste vahemik ei pruugi aga konkreetses kohas
sugugi mõistlik olla. Mida vähem on lubatud väärtusi, seda rohkem on lootust, et
näpuveana sisestatud valed andmed läbi ei lähe. Arvu puhul saab näiteks seada
alam- ja ülempiiri. Kui tüübi ulatust piiratakse, siis tuleb elemendi sisse
eraldi elemendiks xs:simpleType. Selle sisse xs:restriction, mille base-
atribuudiga määratakse ära, milline tüüp aluseks võetakse. Ja xs:restrictioni
sisse siis omakorda loetelu täiendavatest piirangutest.
Juku
Juurikas
1989
Sobivad tüübid saab ka eraldi välja kirjutada. Siis ei lähe hilisem andmestiku
määratlemine liialt pikaks. Järgnevalt siis näide täisarvu kohta, kus seatakse
alumine ja ülemine piir. Nimetüübis olev regulaaravaldis näitab, et praegusel
juhul peab nimi algama suurtähega (üks täht vahemikus A-st Z-ni ning edasi tuleb
üks või rohkem (mida määrab +) väikest tähte. Täpitähed tuleks loetellu eraldi
lisada, kui neid ka lubada. Joogitüübile on jäetud võimalus olemasolevate
väärtuste hulgast valida. Lisaks on levinumate piirangute seas veel pikkuse
jaoks minLength, length ja maxLength.
Juku
Juurikas
1989
Coca-Cola
Ülesandeid
* Koosta piirang Eesti Vabariigi valitsuse määruse aastanumbri kohta.
Aastanumbri väärtus peab olema vähemalt 1918.
* Koosta piirang parooli jaoks. Pikkus peab olema vähemalt kuus tähte.
* Koosta skeem auto andmete jaoks. Registrimärk peab olema kujul kolm numbrit ja
kolm tähte, omaniku perekonnanimi peab algama suure tähega ja ülejäänud tähed
peavad olema väikesed.
Pikemad andmestikud
Elemente võib olla ka hulgem üksteise sees ning seal igaühes omakorda
alamelemendid. Kui elementide arv pole piiratud, siis selle tähistamiseks sobib
atribuudi maxOccurs väärtus unbounded.
Juku
Juurikas
1963
Juku
Kaalikas
1961
Kalle
Kaalikas
1975
Mari
Maasikas
1981
Oskar
Ohakas
1971
Kui sama ülesehitusega elementi soovitakse kasutada mitmel pool, siis on otse
loomulik, et ta tuleb eraldi ära kirjeldada. Järgnevas näites on nii õpetaja kui
õpilased isikutüüpi ning pääseb eesnime ja muude isikuandmete mitmekordsest
kirjeldamisest.
Nurgametsa kooli 7. klass
Juku
Juurikas
1963
Juku
Kaalikas
1991
Kalle
Kaalikas
1991
Mari
Maasikas
1992
Taavi
Ohakas
1992
Kui andmestik paisub veel suuremaks ja keerukamaks, siis saab skeemid jagada
laiali mitmesse faili. Nõnda võib üksikutes failides defineerida kogu dokumendi
jaoks vajalikud tüübid ning hiljem alles neid vajalikes kohtades pruukida. Siin
ühes failis kõigepealt defineeritakse tänavatüüp (mis praegusel juhul võib
koosneda kuni kolmest sõnast) ja indeksitüüp. Nende põhjal ehitatakse kokku
aadressitüüp. Katseks on defineeritud ka üks aadress, kuid see ei ole
kohustuslik.
Edasi saab teises failis sisse lugeda aadressikontrollifailist tüübikirjeldused
ning neid oma kirjelduse juures kasutada. Nagu näha, siinse osakonnatüübi juures
märgitakse, et aadress on aadressitüüpi. See pikk ja keeruline tüüp on aga juba
eelnevalt defineeritud failis nimega aadressikontroll.xsd, mis xs:include käsuga
sisse loetakse.
Nii ongi kogu süsteem jaotatud kolme faili. XML-andmefail loeb osakonna tüübi
välja failist osakonnakontroll.xsd. See aga omakorda kasutab veel faili
aadressikontroll.xsd.
Kultuuriosakond
17655
Lai
Ülesandeid
* Koosta skeem ülevaatuse läbinud autode loetelu kuvamiseks. Iga auto kohta
registrinumber, mark, valmimisaasta, omanik. Sea tüüpidele mõistlikud piirangud.
* Koosta skeem arvuti võimalike omaduste ja osade kirjeldamiseks. Samuti sea
elementide väärtustele piirangud, mis võimalust mööda vähendaksid näpuvigu.
Rekursiivsed andmed, sugupuu
Skeemi üheks heaks omaduseks on võimalus defineerida üksteisesse sisenevaid
samatüübilisi andmeid. Sellist andmestruktuuri nimetatakse rekursiivseks. Tuleb
ta ette näiteks failisüsteeme, kus kataloogid võivad sisaldada faile ja
katalooge, viimased taas omakorda faile ja katalooge ning nõnda edasi. Või
siinses näites, kus inimese elemendi sees on tema lapsed. Ning laste sees on
jällegi loetelu inimestest, kellel igaühel taas võivad lapsed olla. Sellise
struktuuri saab kirja panna nõnda, kus sisenevalt korduv tüüp on eraldi
defineeritud ning ta enese sees sisaldab ka sama tüüpi elemente. Et ehkki laste
loetelu juures ei ole isikutüübi defineerimine veel lõppenud, võib juba määrata,
et laste sees on loetelu määramata arvust isikutüüpi inimestest. Siinne skeem
sobib kirjelduseks sugupuule, mis omaette andmestikuna juba eelpool näidati.
Ülesandeid
* Koosta rekursiivse andmestruktuuri skeem kirjeldamaks kataloogides asuvaid
faile ja alamkatalooge. Testi skeemi sobivust tegelike andmetega.
* Koosta skeem suurfirma organisatsiooni kirjeldamiseks. Kus firma jaguneb
osakondadeks, igal neist võivad olla aga omakorda alamosakonnad. Osakonnas on
töötajad, neil igaühel ametinimetus ja palk.