XML DTD paskirtis DTD (angl. Document Type Definition) paskirtis nusakyti, iš kokių blokų gali būti sudarytas XML (o taip pat ir HTML) dokumentas. Taigi DTD apibrėžia dokumento struktūrą išvardindama leistinus elementus ir jų atributus. Kodėl verta naudoti DTD? 1) Naudojant DTD galima susikurti savą XML dokumento formatą; 2) Žmonių grupės gali susitarti keistis duomenimis pagal tam tikrą DTD aprašą; 3) Galima programiškai patikrinti, ar tam tikri duomenys (Jūsų pačių sukurti ar paimti iš kur kitur) tenkina DTD aprašą. Vidiniai ir išoriniai DTD aprašai DTD aprašas gali būti XML failo viduje. Šiuo atveju jis įterpiamas į žymę DOCTYPE naudojant tokią sintaksę: <!DOCTYPE root-element [element-declarations]> XML failo su įterptu DTD aprašu pavyzdys: <?xml version="1.0"?> <!DOCTYPE note [ <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> ]> <note> <to>petras</to> <from>jonas</from> <heading>priminimas</heading> <body>paskambink!</body> </note> Jei DTD aprašas yra atskirame faile, jis įterpiamas į žymę DOCTYPE naudojant tokią sintaksę: <!DOCTYPE root-element SYSTEM "failo_vardas"> Tas pats XML failas, tik DTD aprašas kitame faile: <?xml version="1.0"?> <!DOCTYPE note SYSTEM "note.dtd"> <note> <to>petras</to> <from>jonas</from> <heading>priminimas</heading> <body>paskambink!</body> </note> 1
O štai taip atrodo failas "note.dtd" su DTD aprašu: <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> XML dokumentą sudarantys blokai DTD požiūriu XML (o taip pat ir HTML) dokumentą sudaro: a) Elementai b) Atributai c) Esybės d) PCDATA e) CDATA Elementai Elementai yra svarbiausi XML dokumento komponentai (paskaitoje apie HTML buvo vadinami žymėmis). Elementai gali apimti tekstą, kitus elementus, o gali būti tušti. Elementų pavyzdžiai: <body>tekstas</body> <message>tekstas</message> Atributai Atributuose pateikiama papildoma informacija apie elementus. Atributai visada talpinami atidarančioje elemento žymėje. Atributai visuomet sudaryti iš porų vardas/reikšmė. Pvz.: <img src="paveikslas.gif"/>. Kadangi elementas tuščias, tai uždaromas simboliu "/". Esybės Kai kurie simboliai XML kalboje turi specialią reikšmę, pvz., simbolis "<" reiškia XML žymės pradžią. Jei reikia tekste įterpti šį simbolį, vietoje jo rašoma tam tikra simbolių kombinacija, vadinama esybe. Apdorojant XML dokumentą XML analizatoriaus programa, esybės pakeičiamos atitinkamais simboliais. Esybių pavyzdžiai: Esybė < < > > & Simbolis & " " ' ' PCDATA PCDATA reiškia analizuojami simboliniai duomenys (angl. parsed character data). Juose sutiktos elementų žymės traktuojamos kaip elementai, o juose esančios esybės pakeičiamos atitinkamais simboliais. Taigi duomenyse negali būti simbolių "<", ">", "&", jie turi būti pakeisti atitinkamomis esybėmis. 2
CDATA CDATA reiškia tiesiog simbolinius duomenis. Juose esančios elementų žymės nėra traktuojamos kaip elementai, o esybės nėra pakeičiamos. Elementų deklaravimas DTD apraše XML elementai deklaruojami naudojant tokią sintaksę: <!ELEMENT element-name category> <!ELEMENT element-name (element-content)> Jei elementas tuščias, kaip kategorija nurodomas raktinis žodis EMPTY: <!ELEMENT element-name EMPTY> Jei elementas gali apimti tik analizuojamus simbolinius duomenis, tarp skliaustų rašoma #PCDATA: <!ELEMENT element-name (#PCDATA)> Jei elementas gali apimti bet kokius duomenis, kaip kategorija nurodomas žodis ANY: <!ELEMENT element-name ANY> Jei elementas turi vaikinių elementų, jie išvardijami skliaustuose atskiriant kableliais: <!ELEMENT element-name (child1,child2,...)> XML dokumente vaikai gali pasirodyti tik ta pačia tvarka, kokia jie buvo išvardinti apraše. Vaikai taip pat gali turėti vaikų. Be to, vaikiniai elementai taip pat turi būti deklaruoti. Pvz.: <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> Vaikiniams elementams galima nurodyti leistiną pasirodymų skaičių: <!ELEMENT element-name (child1,child2+,child3*,child4?)> Šis užrašas reiškia, kad elementas child1 elemento element-name viduje privalo pasirodyti vieną ir tik vieną kartą, prie child2 esantis + reiškia 1..n kartų, prie child3 esanti * 0..n kartų, o prie child4 esantis? 0..1 kartą. Taip pat galima nurodyti, kad gali pasirodyti vienas iš kelių vaikinių elementų, pvz.: <!ELEMENT element-name (child1 child2 child3)> Atributų deklaravimas Atributai deklaruojami naudojant tokią sintaksę: <!ATTLIST element-name attrib-name attrib-type default-value> 3
DTD pavyzdys: <!ATTLIST payment type CDATA "check"> XML pavyzdys: <payment type="check"/> Kaip atributo tipas (attrib-type) dažniausiai nurodoma CDATA arba skliaustuose išvardijamos galimos reikšmės, pvz., (val1 val2...). Kaip numatytąją reikšmę (default-value) galima nurodyti: 1) reikšmę, 2) raktinį žodį #REQUIRED, jei atributas privalo būti, bet nežinome tinkamos numatytosios reikšmės, 3) raktinį žodį #IMPLIED, jei atributas nebūtinas ir nežinome tinkamos numatytosios reikšmės, 4) raktinį žodį #FIXED ir reikšmę. Šiuo atveju atributas turės fiksuotą reikšmę ir nebus galima jos keisti. XML dokumente nurodžius kitą reikšmę, XML analizatorius duos klaidos pranešimą. Atributai vs. vaikiniai elementai XML kalboje nėra griežtų taisyklių, kada naudoti atributus, o kada vaikinius elementus. Tą pačią informaciją galima pateikti keliais būdais. Pvz., naudojant vaikinius elementus: <note> <date> <day>12</day> <month>11</month> <year>2002</year> </date> <to>petras</to> <from>jonas</from> <heading>priminimas</heading> <body>paskambink!</body> </note> O čia tas pats pavyzdys naudojant atributus: <note day="12" month="11" year="2002" to="petras" from="jonas" heading="priminimas" body="paskambink!"> </note> Pagrindinės problemos, kylančios naudojant atributus: 1) atributai negali turėti kelių reikšmių (vaikiniai elementai gali); 2) atributus sunku išskleisti (pvz., data anksčiau pateiktame pavyzdyje); 3) sunkiau patikrinti, ar atributai tenkina DTD aprašą. Taigi nors atributai itin populiarūs HTML kalboje, bet XML kalboje jų reiktų vengti, vienintelė išimtis jei atributas naudojamas kaip elemento identifikatorius. 4
Esybių deklaravimas Esybės tai kintamieji, naudojami apibrėžti standartinių frazių ar specialių simbolių santrumpas. Esybės apibrėžiamos naudojant tokią sintaksę: <!ENTITY entity-name "entity-value"> DTD pavyzdys: <!ENTITY writer "Donald Duck."> <!ENTITY copyright "Copyright W3Schools."> XML pavyzdys: <author>&writer;©right;</author> Taigi esybės XML dokumente sudarytos iš trijų dalių: ampersendo, vardo ir kabliataškio. Esybės gali būti deklaruotos tiek DTD viduje, tiek ir kitame faile. XML ir DTD failų pavyzdžiai Sakinio skaidymo į sakinio dalis pavyzdys. Failas sakinys.xml. <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE tekstas SYSTEM "sakinys.dtd"> <tekstas> <sakinys> <veiksnys> <pazyminys> Mažas </pazyminys> <pazymimasis_zodis> vaikas </pazymimasis_zodis> </veiksnys> <tarinys> mato </tarinys> <aplinkybe> greitai </aplinkybe> <papildinys linksnis="g"> <pazyminys> bėgantį </pazyminys> <pazymimasis_zodis> šunį </pazymimasis_zodis> </papildinys> </sakinys> </tekstas> 5
Failas sakinys.dtd. <!ELEMENT tekstas (sakinys*)> <!ELEMENT sakinys (tarinys veiksnys papildinys aplinkybe)*> <!ELEMENT veiksnys (pazyminys*,pazymimasis_zodis)> <!ELEMENT tarinys (#PCDATA)> <!ELEMENT aplinkybe (#PCDATA)> <!ELEMENT papildinys (pazyminys*,pazymimasis_zodis)> <!ATTLIST papildinys linksnis (K N G In) #REQUIRED> <!ELEMENT pazyminys (#PCDATA)> <!ELEMENT pazymimasis_zodis (#PCDATA)> Žodžio skaidymo į priešdėlius, šaknį, priesagas ir galūnę pavyzdys. Failas zodis.xml. <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE tekstas SYSTEM "zodis.dtd"> <tekstas> <zodis> <kamienas> <saknis> Kišk </saknis> </kamienas> <galune> is </galune> </zodis> <zodis> <kamienas> <priesdelis dalelyte="neig"> ne </priesdelis> <priesdelis> pri </priesdelis> <priesdelis dalelyte="sangr"> si </priesdelis> <saknis> kiškia </saknis> <saknis> kopūstau </saknis> <priesaga> dav </priesaga> </kamienas> <galune> o </galune> </zodis> </tekstas> 6
Failas zodis.dtd. <!ELEMENT tekstas (zodis*)> <!ELEMENT zodis (kamienas,galune)> <!ELEMENT kamienas (priesdelis*,saknis+,priesaga*)> <!ELEMENT priesdelis (#PCDATA)> <!ATTLIST priesdelis dalelyte (neig sangr) #IMPLIED> <!ELEMENT saknis (#PCDATA)> <!ELEMENT priesaga (#PCDATA)> <!ELEMENT galune (#PCDATA)> XML dokumento atitikimo DTD aprašui tikrinimas Patikrinti XML dokumento atitikimą DTD aprašui galima naudojantis Java kalbos bibliotekomis. Programos Java kalba pavyzdys (failas ValidateXML.java) pateiktas 1 priede (čia įsiūtas failo sakinys.xml tikrinimas). Programa kompiliuojama komandinėje eilutėje įvedus javac ValidateXML.java, o paleidžiama java ValidateXML. Programa nurodo eilutės, kurioje įvyko klaida, numerį, o taip pat išveda į ekraną klaidos pranešimą. Naršyklėje Internet Explorer 5 galima XML dokumento atitikimą DTD aprašui patikrinti naudojantis kalba JavaScript. Toliau pateiktas HTML dokumentas su JavaScript fragmentu, kuris tikrina įsiūtą failą zodis.xml. Eilutės su klaida numeris ir klaidos pranešimas išvedamas naršyklės lange. <HTML> <HEAD> <TITLE>XML Parser Demo</TITLE> </HEAD> <BODY> XML Parser Demo<BR> <SCRIPT LANGUAGE="JavaScript"> var xmldoc = new ActiveXObject("Microsoft.XMLDOM"); xmldoc.async="false"; xmldoc.validateonparse="true"; xmldoc.load("zodis.xml"); document.write("<br />Error Code: "); document.write(xmldoc.parseerror.errorcode); document.write("<br />Error Reason: "); document.write(xmldoc.parseerror.reason); document.write("<br />Error Line: "); document.write(xmldoc.parseerror.line); </SCRIPT> </BODY> </HTML> Literatūra 1. http://www.w3schools.com/dtd/default.asp 2. http://javaxden.blogspot.com/2007/08/xml-validation-with-dtd-in-java.html 7
1 priedas. Failas ValidateXML.java import java.io.fileinputstream; import javax.xml.parsers.documentbuilder; import javax.xml.parsers.documentbuilderfactory; import javax.xml.transform.outputkeys; import javax.xml.transform.transformer; import javax.xml.transform.transformerfactory; import javax.xml.transform.dom.domsource; import javax.xml.transform.stream.streamresult; import org.w3c.dom.document; import org.xml.sax.saxexception; import org.xml.sax.saxparseexception; public class ValidateXML { public static void main(string args[]) { try{ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setvalidating(true); DocumentBuilder builder = factory.newdocumentbuilder(); builder.seterrorhandler(new org.xml.sax.errorhandler() { //To handle Fatal Errors public void fatalerror(saxparseexception ex)throws SAXException {System.out.println("Line: " +ex.getlinenumber() + "\nfatal Error: "+ex.getmessage());} //To handle Errors public void error(saxparseexception e)throws SAXParseException {System.out.println("Line: " +e.getlinenumber() + "\nerror: "+e.getmessage()); } //To Handle warnings public void warning(saxparseexception err)throws SAXParseException {System.out.println("Line: " +err.getlinenumber() + "\nwarning: "+err.getmessage());} }); Document xmldocument = builder.parse(new FileInputStream("sakinys.xml")); DOMSource source = new DOMSource(xmlDocument); StreamResult result = new StreamResult(System.out); TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newtransformer(); transformer.setoutputproperty(outputkeys.doctype_system, "sakinys.dtd"); transformer.transform(source, result); } catch (Exception e) {System.out.println(e.getMessage()); } } } 8