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.