Praktikum: XML skeemifailid(VR2.3)
Teooria
XML on standardiseeritud märgendikeel. Selle eesmärgiks on struktureeritud info hoidmine enamasti transpordi eesmärgil. Kuna XML on laiendatav, siis baseeruvad sellel keelel väga paljud standardiseeritud struktuurid - XHTML, RSS, SOAP, SVG jne.
Selleks, et XML-i edukalt tarnida ühest süsteemist teise on vaja kontrollida selle valiidsust. See on vajalik selleks, et ühest süsteemist teise viies ei esineks vigu. Mõlemad süsteemid kusjuures peavad kasutama sama valideerimismeetodit.
XML-i puhul on valideerimisvõimalusteks Dokument Type Definition (DTD) ja XML Schema (XSD).
- DTD meetodiga määratakse ära lubatud struktuurelemendid, nende attribuudid ning nende väärtustüübid.
- XSD meetod on võimalusterohkem, kui DTD, ning sellega on võimalik kirjeldada palju keerulisemaid struktuure valideerimiseks.
Aga milleks me ikkagi valideerime XML-e?
XML on enamikel juhtudel elulise tähtsusega rakenduse toimimisel. Kui me valideerime XML-i ja leiame enne selle kasutamist, et see ei ole soovitud formaati, siis sellega saame me hoida ära paljud ebameeldivad üllatused, mis võivad tekkida. Siiski see ei välista nende tekkimist.
Document Type Definition - DTD
DTD puhul on tegemist XMList eraldi seisva keelega. Sellega on võimalik ära määrata elementide ja nende attribuutide esinemist. Elementide ja attribuutide väärtuste tüüpi on võimalik määrata väga kesiselt.
DTD struktuurikirjeldust saab määrata XML-i jaoks kahte moodi:
- Inline - ehk siis sama XML'i sees kirjeldatakse ära selle juurelemendi alamelementide ja -attribuutide puu.
- External - ehk XML-i struktuur kirjeldatakse ära XML-ist eraldi failina.
Esimest varianti tasub kasutada vaid juhul, kui tegu on väga väikese struktuuiga XML-iga. Ehk siis enamasti õppimise ja testimise raames. Teine variant on mõeldud kasutamiseks juba väheke keerukamate XML struktuuride kirjeldamise puhuks.
Selle XML-i struktuuri kirjeldamise peamisteks märgenditeks on:
- <!ELEMENT elemendi_nimi (alam_element1, alam_element2)> või <!ELEMENT elemendi_nimi (elemendi_andmetüüp)>
- Elemendi tüüpideks on: W3Schools
- #PCDATA - kontrollitakse väärtust, et temas ei oleks < ja & sümboleid.
- #CDATA - väärtust ei kontrolita, et temas ei oleks < ja & sümboleid.
- EMPTY - elemendil ei ole väärtust
- Elemendi tüüpideks on: W3Schools
- <!ATTLIST elemendi_nimi attribuudi_nimi andmetüüp nõutavus>
- Andmetüübid: W3Schools
- CDATA - Tekstväärtus
- (en1|en2|..) - Üks võimalik väärtus enumereeritud loetelust
- ID - Väärtus on unikaalne id
- IDREF - Väärtus on mõne teise elemendi ID
- IDREFS - Väärtus on loetelu teiste elemendide ID-dest
- NMTOKEN - Väärtus on valiidne XML-i nimi
- NMTOKENS - Väärtuseks on valiidsed XML-i nimed
- ENTITY - Väärtus on üksuse nimi
- ENTITIES - Väärtus on üksuste loetelu
- NOTATION - Väärtus on märke nimi.
- xml: - Väärtus on eelnevalt määratud XMLi väärtus
- Nõutavus: W3Schools
- väärtus - Vaikimisi attribuudi väärtus
- #REQUIRED - Väärtus on vajalik.
- #IMPLIED - Väärtus on valikuline
- #FIXED väärtus - fikseeritud väärtus
- Andmetüübid: W3Schools
Internal DTD
Nagu mainitud, kirjeldatakse sellisel juhul ära struktuur XML'i enda sees:
<?xml version="1.0" encoding="utf-8">
<!DOCTYPE HOUSE [
<!ELEMENT HOUSE (ROOM*)>
<!ELEMENT ROOM (DOOR+,WINDOW+)> <!-- + * ? tähistavad esinevust failis -->
<!ELEMENT DOOR (#PCDATA)>
<!ELEMENT WINDOW (#PCDATA)>
<!ATTLIST HOUSE ADDRESS CDATA #REQUIRED>
<!ATTLIST ROOM OWNER CDATA #IMPLIED>
]>
<HOUSE ADDRESS="Raja 3C">
<ROOM OWNER="User1">
<DOOR />
<WINDOW />
<WINDOW />
</ROOM>
<ROOM OWNER="User2">
<DOOR />
<WINDOW />
<WINDOW />
<WINDOW />
</ROOM>
<ROOM>
<DOOR />
</ROOM>
<ROOM OWNER="User1">
<DOOR />
<WINDOW />
</ROOM>
</HOUSE>
External DTD
Sellisel juhul asub struktuurikirjeldus eraldi failis. Oletame, et meil on selleks failiks House.dtd
<!ELEMENT HOUSE (ROOM*)>
<!ELEMENT ROOM (DOOR+,WINDOW+)> <!-- + * ? tähistavad esinevust failis -->
<!ELEMENT DOOR (#PCDATA)>
<!ELEMENT WINDOW (#PCDATA)>
<!ATTLIST HOUSE ADDRESS CDATA #REQUIRED>
<!ATTLIST ROOM OWNER CDATA #IMPLIED>
Ja XMLiks House.xml
<?xml version="1.0" encoding="utf-8">
<!DOCTYPE HOUSE SYSTEM "House.dtd">
<HOUSE ADDRESS="Raja 3C">
<ROOM OWNER="User1">
<DOOR />
<WINDOW />
<WINDOW />
</ROOM>
<ROOM OWNER="User2">
<DOOR />
<WINDOW />
<WINDOW />
<WINDOW />
</ROOM>
<ROOM>
<DOOR />
</ROOM>
<ROOM OWNER="User1">
<DOOR />
<WINDOW />
</ROOM>
</HOUSE>
DTD loomiseks ei ole Visual Studio keskkonnas olemasoleva XMLi peale genereerimiseks automaatseid vahendeid. DTD tuleb kirjutada käsitsi.
Valideerimine
Valideerimisel tuleb silmas pidada, et ei saa kasutada Linq to XML meetodit, kuna ee ei toeta DTD-d. XML'i valideerimiseks DTD põhjal kasutame external DTD näidet:
// Set the validation settings.
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
settings.ValidationType = ValidationType.DTD;
settings.ValidationEventHandler += new ValidationEventHandler ((sender, e) =>{
System.Windows.Forms.MessageBox.Show("Validation Error: " + e.Message);
});
// Create the XmlReader object.
XmlReader reader = XmlReader.Create("House.xml", settings);
// Parse the file.
while (reader.Read());
XML Schema Definition (XSD)
XSD puhul on tegemist alternatiiviga DTDle. Kusjuures XMLi struktuur kirjeldatakse ära samuti XML märgendikeeles. XSD struktuuris saab kirjeldada, mis tohib, mis ei tohi olla ja kuidas peavad olema need elemendid määratud. Selles märgendistandardis saab kirjeldada väga keerulisi struktuure.
Selles saab kirjeldada:
- Elementide järjestikulist esinemist.
- Nende esinemiste arvu
- Attribuutide esinemisi elementides
- Attribuutide ja elementide väärtustüüpe.
- Lisaks on võimalik määrata andmetele tingimusi.
- Oluliseks saab teha nende esinemise järjekorra
XSDs leiduvad elemendid saab jämedalt jagada kaheks:
- Simple type
- Complex type
Simple type
Tegemist on elemendikirjeldusega, millel ei ole attribuute ega ka alamelemente vaid lihtsalt väärtus.
<elementName>value</elementName>
Complex type
Sellisel andmetüübil ehk elemendil võib olla alamelemente ja attribuute.
Complex type lähemaks uurimiseks palun kasutada järgnevaid viiteid:
XSD genereerimine Visual Studio keskkonnas
Võrreldes DTDga on XSD'l hea eelis. Seda ei pea käsitsi kirjutama. Selleks saab kasutada Visual Studio arenduskeskkonna vahendeid. Selleks loote või avate VS keskkonnas XML'i ja vajuta "Create Schema" nuppu tööriistaribal. Peale seda genereeritakse teile XSD fail, mida antud hetkel ei ole veel salvestatud kuskile. selle peate ise salvestama soovitud asukohta.
Valideerimine
XML'i valideerimiseks XSD-ga saab kasutada järgnevat meetodit:
// Oletame, et meil on House.xml jaoks ka fail House.xsd
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add("", "House.xsd");
// Laeme sisse House.xml-i
XDocument doc = XDocument.Load("House.xml");
// Ja üritame valideerida
custOrdDoc.Validate(schemas, (o, e) =>
{
// Iga vea kohta avatakse teade
System.Windows.Forms.MessageBox.Show(e.Message);
});
Extensible Stylesheet Language Transformations (XSLT)
Jämedalt öeldes on XSLT teemakirjeldus nagu CSS on HTMLi jaoks. See on mõeldud XML andmete HTMLiks transformeerimiseks. Seda selleks, et neid andmeid oleks võimalik inimlikul kujul lugeda. Siiski ei ole see mõeldud kasutajaliideste loomiseks! Kuigi see on võimalik.
XSLT puhul on väga tähtsal kohal XPath'i kasutamise oskamine. Selle adresseimismeetodiga liigutakse transformeerimise andmete saamiseks XML-is ringi.
XPath süntaksi tarbeks vaadake antud viidet.
XSLT viitamine XMLis
Selleks, et XMLi jaoks XSLT template'i kasutataks tuleb see määrata XML'is peale <?xml ... ?> tagi
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="House.xsl"?>
...
<xsl:template>
Antud elemendiga määratakse ära stiili põhi. Näide:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/"> <!-- xsl:template element vastab XML'i juurelemendile -->
<html>
<body>
Mingi nimekiri.
<ul>
<li>Element 1</li>
<li>Element 2</li>
<li>Element 3</li>
<li>Element 4</li>
</ul>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
<xsl:value-of>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
Mingi nimekiri.
<ul>
<li><xsl:value-of select="HOUSE/ROOM"/></li> <!-- xsl:value-of element vastab XML'i HOUSE juurelemendi esimesele ROOM elemendile -->
<li>Element 2</li>
<li>Element 3</li>
<li>Element 4</li>
</ul>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
<xsl:for-each>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
Mingi nimekiri.
<ul>
<xsl:for-each select="HOUSE/ROOM"> <!-- valime järjest tsüklis kõik ROOM elemendid -->
<li><xsl:value-of select="@OWNER"/></li> <!-- xsl:value-of tagastab ROOM elemendi OWNER attribuudei väärtuse -->
</xsl:for-each>
</ul>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
<xsl:sort>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
Mingi nimekiri.
<ul>
<xsl:for-each select="HOUSE/ROOM">
<xsl:sort select="@OWNER"/> <!-- sorteerime omaniku järgi -->
<li><xsl:value-of select="@OWNER"/></li>
</xsl:for-each>
</ul>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
<xsl:if>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
Mingi nimekiri.
<ul>
<xsl:for-each select="HOUSE/ROOM">
<xsl:if test="0 = count(WINDOW)"/> <!-- kuvame ainult ruumi omanikud, kelle ruumil pole aknaid -->
<li><xsl:value-of select="@OWNER"/></li>
</xsl:if>
</xsl:for-each>
</ul>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
<xsl:choose>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
Mingi nimekiri.
<ul>
<xsl:for-each select="HOUSE/ROOM">
<xsl:choose>
<xsl:when test="0 = count(WINDOW)">
<li bgcolor=red><xsl:value-of select="@OWNER"/></li> <!-- kuva punaselt, kui pole aknaid -->
</xsl:when>
<xsl:otherwise>
<li><xsl:value-of select="@OWNER"/></li> <!-- kuva tavaliselt -->
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:for-each>
</ul>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Materjali lugemiseks
- http://nwalsh.com/docs/tutorials/xsl/xsl/frames.html
- http://cs.au.dk/~amoeller/XML/transformation/
- http://www.ibm.com/developerworks/xml/library/x-hands-on-xsl/index.html?dwzone=xml
- Best Practice
- http://www.xmlplease.com/xsltidentity
Ülesanded
Käsi_hoitud_tegevus
Loo varasemalt tehtud retseptiraamatu XMLi põhjal skeemifail
- Kontrolli, et XML andmefail valideeruks vastu skeemifaili
- Paranda genereeritud XML skeemifaili nii, et see töötaks kõigi andmetega
Loo varasemalt tehtud arvutiklassi XMLi põhjal skeemifail
- Kontrolli, et XML andmefail valideeruks vastu skeemifail
- Paranda genereeritud XML skeemifaili nii, et see töötaks erinevate andmetega
Käsi_mittehoitud_tegevus
Loo XML andmefail, mis võimaldab hoida randade kohta infot(inimeste arv, temperatuur, veetemperatuur)
- Loo XML skeemifail, mis võimaldaks XML andmefaili valideerida
- Kontrolli üle skeemifaili andmetüübid ning vajadusel paranda neid