Érvényes XML dokumentumok

Érvényes XML dokumentumnak nevezzük azon jól-formázott XML dokumentumokat, amelyek logikai felépítése és tartalma teljes mértékben megegyezik az XML dokumentumban meghatározott (vagy külső fájlban meghatározott és az XML dokumentumhoz csatolt) szabályoknak. Ezen szabályok megfogalmazhatóak:

A sémanyelvek célja a validálás, le kell tudni írni XML dokumentumok egy osztályának szerkezetét. A validációt az XML-feldolgozó végzi és ellenőrzi, hogy a dokumentum megfelel-e a sémában leírtaknak. Bemenet a dokumentum és a séma, a kimenet pedig a validációs jelentés és opcionálisan a Post-Schema Validated Infoset (PSVI) - mely a következő fejezetben lesz tárgyalva.

A sémanyelvek eszközrendszert biztosítanak

A sémanyelvek egy tűzfalanalógiával élve, megóvják az alkalmazásokat a váratlan/értelmezhetetlen formátumoktól, információktól. Nyitott tűzfal esetén megenged mindent ami nem tiltott (ilyen például a Schematron), vagy zárt tűzfal, ami tilt mindent, ami nem megengedett (pl. XML Schema ).

A sémanyelvek egyfajta osztályozása

Azonban ezek a séma nyelvek sem születnek csak úgy, minden korlát nélkül. A korábbiakban említett, XML technológia családok résznél láttuk, hogy számos ISO szabvány is felsorolható. Ezek közé tartozik a Document Schema Definition Languages (DSDL, ISO-19757) is. A szabvány célja bővíthető keretbe foglalni a különböző validációval kapcsolatos feladatokat. A validálás során különböző aspektusokat lehet vizsgálni:

Ezt nehézkes lenne egy nyelv segítségével megoldani, ezért különböző sémanyelvek együttes használatára lehet szükség, melyre tipikus példa a Schematron séma beágyazása az XML sémába. Egy XML sémanyelv a megszorítások formalizálása, szabályok leírása vagy a struktúra modelljének megadása. Sok tekintetben a sémák tervezőeszköznek tekinthetőek.

XML dialektusok: DTD és XML séma

Sémák alkalmazásával a validálás során biztosíthatjuk, hogy a dokumentum tartalma megfelel az elvárt szabályoknak, egyszerűbb a feldolgozást megvalósítani. Különböző sémák használatával különbözőképpen validálhatunk. Az XML 1.0 tartalmaz az XML dokumentum struktúra definiálására alkalmas eszközt a DTD-t. A DTD (Document Type Definition) egy eszközkészlet, amelynek segítségével definiálhatjuk milyen elem és attribútum struktúrák engedélyezettek a dokumentumban, ezen felül alapértelmezett értéket adhatunk attribútumoknak, definiálhatunk újrafelhasználható tartalmat és metaadatot is.

A DTD tömör formális szintaxist alkalmaz, amely pontosan megmutatja, mely elemek hol fordulhatnak elő az adott típusú dokumentumban, és hogy az elemeknek milyen tartalmuk és tulajdonságaik lehetnek. A DTD-ben egyedeket is deklarálhatunk, amelyek felhasználhatók a dokumentum példányaiban. Az alábbiakban pedig egy egyszerű példát láthatunk DTD-re:

<!ELEMENT konyv (szerzo, cim, alcim*, kiado,  (fogy_ar|elfogyott )?, ISBN?, iranyitoszam?, leiras?,
                            kulcsszo* ) >
                            <!ELEMENT kulcsszo ( #PCDATA ) >
                            <!ELEMENT leiras ( #PCDATA|bevezeto|torzs ) * >

A DTD által biztosított lehetőségek azonban nem felelnek meg napjaink XML feldolgozó alkalmazásai által támasztott igényeknek.

A legtöbb kritika az alábbiak miatt éri:

  • nem XML szintaxis, amely nem biztosítja az általános célú XML feldolgozó eszközök használatát, mint például az XML elemzők vagy XSLT stíluslapok,

  • nem támogatott az XML névterek használata, amely mára már megkerülhetetlen,

  • nincs támogatás az SQL-ben és a programozási nyelvekben tipikusan rendelkezésre álló adattípusok használatához,

  • nincs lehetőség az elemek környezetfüggő deklarálására (minden elem csak egyszer deklarálható).

Ezek kiküszöbölésére számos XML sémanyelv született. Napjainkban is „élő ” és elterjedten használt sémanyelvek a W3C XML Schema, RELAX NG és Schematron. Míg az első W3C ajánlás, az utóbbi kettő ISO szabványként létezik. A leggyakrabban ezek közül az XML Schema-t használják, bár ennek is vannak hátrányai:

  • A specifikáció nagyon nagy, ami nehézzé teszi a megértést és az implementálást.

  • Az XML-alapú szintaxis bőbeszédűséghez vezet a séma definícióban, ami nehezíti az XSD olvasását és írását.

Legfontosabb XML Schema elemek

Az XML sémadefiníciót egy külön fájlban kell létrehozni, amelyre ugyanazon jól-formázottsági szabályok vonatkoznak mint egy XML dokumentumra, melyeket pár kiegészítés követ:

  • egyetlen legfelső szintű elemet tartalmazhat a séma schema néven,

  • az összes sémában használt elemnek és jellemzőnek a "http://www.w3.org/2001/XMLSchema" névtérhez kell tartozni, ezzel is jelezve, hogy XML-sémáról van szó, leggyakrabban pedig xsd vagy xs prefix-ként használják.

A schema elemnek a legfontosabb attribútuma az elementFormDefault, ami megadja, hogy az elemeknek szükségszerűen minősítettnek (qualified) kell lenniük vagy ez mellőzhető. Hasonlóan igaz ez az attribútumokra (attributeFormDefault)is. A tapasztalat alapján a legjobb, ha minősített nevekkel dolgozunk végig, így nem érhet meglepetés egyetlenegy feldolgozónál sem.

Egy XML séma dokumentum építőkövei az elemek (element). Az elemek tárolják az adatokat és határozzák meg a dokumentum felépítését. XML Schema-ban a következő módon lehet definiálni egyszerű elemeket:

<xs:element name="name" type="xs:string" default="unknown" />

példa – Egyszerű elem definiálása

A name kötelező, ennek kell majd a dokumentumban megjelennie. A type határozza meg milyen típusú értékeket tartalmazhat az adott elem. Vannak előre definiált típusok, melyek közel hasonlóak a Java nyelvben megismertekhez ( pl: xs:integer, xs:string vagy xs:boolean), de létrehozhatunk saját típusokat is. Az értéket, amit az elem felvesz tovább pontosíthatjuk default és fixed tulajdonságok megadásával. Ha nem adunk meg semmilyen értéket a dokumentumban, akkor az alkalmazás a default értéket fogja használni. Ha a fixed meg van adva, akkor csak az ott megadott értéket veheti fel.

Meg lehet adni a számosságot, ami azt mondja meg hányszor fordulhat elő az elem az adott pozícióban. A minOccurs és a maxOccurs attribútumokban lehet megadni a minimális és a maximális előfordulást. Az alapértelmezett érték mindkettőre 1.

<xs:element name="address" type="xs:string" minOccurs="1" maxOccurs="unbounded">

példa – Elem számosságának megadása

Lehetőség van saját típus létrehozására úgy, hogy az egyes alaptípusokból egy saját típust származtatunk.

<xsd:element name="EV">
	<xsd:simpleType>
		<xsd:restriction base="xsd:gYear">
			<xsd:minInclusive value="1954"/>
			<xsd:maxInclusive value="2003"/>
		</xsd:restriction>
	</xsd:simpleType>
</xsd:element>

Restriction kulcsszó segítségével történik a származtatás, úgy hogya restriction elem base jellemzőjének adjuk meg azt a típust, amelyből származtatni szeretnénk a saját típusunkat. A restriction elem gyermekelemeiként megadhatjuk az új típusra vonatkozó megszorításokat. Itt lényegében csak a képzelet szabhat határt a megszorításoknak, mert lényegében mindenre kínál lehetőséget, aminél a reguláris kifejezések használata teljesíti ki a képet.

Struktúrát definiálni komplex elemtípusokkal lehet. A komplex elemtípus két csoportra osztható: egyszerű és összetett tartalommal rendelkező. Mindkettőnek lehet attribútuma, de csak az összetett tartalommal rendelkezőnek lehet gyermekeleme. Egyszerű tartalommal rendelkező definiálása:

<xs:complexType name="address">
	<xs:simpleContent>
		<xs:attribute name="city" type="xs:string" /> 
	</xs:simpleContent>
</xs:complexType>

példa – Egyszerű tartalommal rendelkező elem definiálása

Összetett tartalommal rendelkező típus definiálása:

<xs:complexType name="address">
	<xs:complexContent>
		<xs:sequence>
			<xs:element name="street" type="xs:string"/>
			<xs:element name="streetnumber" type="xs:integer"/>
		</xs:sequence> 
	</xs:complexContent>
</xs:complexType>

példa – Összetett tartalommal rendelkező elem definiálása

Komplex elemtípusoknál meg kell adni egy kompozitort. A kompozitor mondja meg, hogyan kell kezelni a gyermekelemeket. Három kompozitor létezik:

  • sequence

  • choice

  • all

A sequence azt jelzi, hogy a gyermekelemeknek abban a sorrendben kell megjelenniük a dokumentumban, mint ahogyan a sémában deklarálták. All esetén a sorrend tetszőleges. Ha choice van megadva, akkor csak az egyik gyermekelem jelenhet meg.

A komplex típusok újrafelhasználhatóak, ha egy elemtől függetlenül vannak deklarálva, úgy viselkednek mint egy globális definíció. Új elem deklarálásakor meg kell adni típusnak a komplex típus nevét.

A legvégére pedig a hivatkozások kezelése maradt, ami nagyban megkönnyíti a redundáns adatokkal való munkát, pontosabban lecsökkenti a jelenlétüket. Ha a sémában egy másik elemre szeretnénk hivatkozni akkor azt a „ID”, illetve „IDREF” típusokkal érhetjük el. Az „ID” típussal azonosítóvá tesszük az elemet, attribútumot. Az „IDREF”-el pedig hivatkozunk egy már létező azonosítóra. Az azonosítóknak az egész dokumentumban egyedieknek kell lenniük. Amennyiben már létező névvel látunk el egy azonosítót, vagy egy nem létezőre hivatkozunk akkor a dokumentum érvénytelen lesz. Az azonosító egy „NCName” típus, amelynek első karakterének kötelezően betűnek vagy aláhúzásnak kell lennie, a többi már a programozó fantáziájától függ.

A következő 2 típus egy kórházi rendszer sémája, egy betegágyat a betegfelvétellel összekötő hivatkozással

<xsd:complexType name="Bed">
	<xsd:sequence />
	<xsd:attribute name="id" type="xsd:ID" use="required" />
	<xsd:attribute name="number" type="xsd:string" use="required" />
</xsd:complexType>

Betegágy típus

<xsd:complexType name="AdmissionInformation">
	<xsd:sequence>
		<xsd:element name="admissionDate" type="xsd:dateTime" />
		<xsd:element name="endDate" type="xsd:dateTime" minOccurs="0" />
	</xsd:sequence>
	<xsd:attribute name="bedRef" type="xsd:IDREF" use="optional"/>
	<xsd:attribute name="medicalAttendantRef" type="xsd:IDREF" use="required" />
	<xsd:attribute name="end" type="xsd:boolean" use="optional" />
	<xsd:attribute name="recovered" type="xsd:boolean" use="optional" />
</xsd:complexType>

Betegfelvétel típus

A „Bed” típusnak 2 attribútuma van: egy „id” nevű azonosító, illetve egy „number” ágyszám. Az „AdmissionInformation” már kicsit méretesebb, de a legfontosabb, hogy rendelkezik két „IDREF” típusú attribútummal: „bedRef” amely a beteg által használt ágyra hivatkozik, illetve a „medicalAttendantRef”, ami pedig a beteg kezelőorvosára.