Érvényes XML dokumentum létrehozása, ellenőrzése és értelme

Mielőtt megismerkednénk a dokumentum típus definíció létrehozására használandó nyelv szintaktikájával, határozzuk meg, mely dokumentumok nevezhetők érvényesnek.
   Érvényes XML dokumentumnak nevezzük azon jólformázott XML dokumentumokat, melyek 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 (megírhatóak) Dokumentum Típus Definíció (rövidebb nevén DTD) vagy XML-séma (cikksorozat következő részében fogjuk tárgyalni) segítségével.

Az XML dokumentumok érvényességének ellenőrzését maga a böngésző nem végzi el a dokumentum értelmezésekor, csupán jólformázottsági ellenőrzést hajt végre a dokumentumon és az esetleges DTD-n (amennyiben tartalmaz ilyet a dokumentum). Az XML dokumentum érvényességének ellenőrzése a feldolgozó program (például egy weblapszkript) feladata. Az esetleges érvényességi hibák esetén hibaüzenetet kapunk, de a dokumentum feldolgozása folytatódhat. A következőkben bemutatunk egy rövidke weblapszkriptet JavaScript nyelvben megírva, amely segítségével nagyon egyszerűen megállapíthatjuk, hogy a dokumentum érvényes-e vagy sem:

<HTML> <HEAD><TITLE>DTD szerinti érvényesség-ellenőrző</TITLE> <SCRIPT LANGUAGE="JavaScript"> function DTD_ellenor(DSO_obj) {   if(DSO_obj.XMLDocument.parseError.errorCode != 0)    {     var msg;     msg = "Hibaszám: "     + DSO_obj.XMLDocument.parseError.errorCode + "\n"        + "fájlpozíció: "   + DSO_obj.XMLDocument.parseError.filepos   + "\n"        + "sor: "           + DSO_obj.XMLDocument.parseError.line      + "\n"        + "karakter: "      + DSO_obj.XMLDocument.parseError.linepos   + "\n"        + "leírás: "        + DSO_obj.XMLDocument.parseError.reason    + "\n"        + "forrás szöveg: " + DSO_obj.XMLDocument.parseError.srcText   + "\n"        + "URL: "           + DSO_obj.XMLDocument.parseError.url;              return alert(msg);    }else return alert("OK"); }        </SCRIPT> </HEAD> <BODY onLoad="DTD_ellenor(document.getElementById('DSO_obj'))"> <!--Az SRC tulajdonságnak adjuk meg az ellenőrizendő XML dokumentum URL-jét: --> <XML ID="DSO_obj" SRC="Leltar Ervenyes.xml"></XML> <H2>DTD-t használó érvényesség-ellenőrző</H2> </BODY> </HTML>
A forrással kapcsolatban érjük be annyival, hogy az XML objektum SRC tulajdonságában adjuk meg az ellenőrizni kívánt XML dokumentum elérési útját (URL). A weblap böngészőben való megnyitása után hibajelentést kapunk az érvényességi hibákról, ellenkező esetben az "OK" üzenet értesít arról, hogy a dokumentum érvényes! Ezen szkript magyarázatába azért nem kívánok belebonyolódni, mivel a cikksorozat későbbi részeiben részletesen fogunk foglalkozni a DSO és weblapszkriptek használatával.

Bizonyára sokakban felmerült a kérdés, vajon mire is jó ez a sok felesleges munka?
Vegyünk rögtön egy példát:
Gondolom sokak számára ismerős a wml kiterjesztés. Akiknek mégsem, azoknak elárulom, hogy a WAP (mobil internet) oldalalak leírására szolgáló jelölőnyelv. Egy WML dokumentum nem más, mint egy DTD-vel ellátott XML dokumentum. Ilyen oldalat bárki bármikor írhat, viszont a feldolgozó szoftver egy bizonyos adatstruktúrát vár el az összes feldolgozandó dokumentumtól. A DTD segítségével biztosítva van, hogy a megírt vagy feldolgozni kívánt dokumentum megfelel az elvártaknak. Ráadásul az egyes DTD-k ismerete alapján bárki készíthet érvényes dokumentumot vagy akár feldolgozó alkalmazást, vagyis a DTD nem más mint egy tervrajz az XML dokumentumokhoz. A DTDnek tartalmazni kell az összes elemet és  jellemzőt, amelyet a dokumentum tartalmazhat.

Dokumentum típus definíció (DTD) létrehozása

A DTD az XML dokumentum fejrészében, az XML fejléc után bárhová elhelyezhető. A DTD deklaráció általános formája:

<!DOCTYPE dokumentumelem_neve DTD>

ahol dokumentumelem_neve a DTDt tartalmazó dokumentum dokumentumelem neve, a DTD pedig az egyes DTD deklarációk összessége. A DTD deklarációk összessége alatt értjük az egyes elemek, jellemzők, egyedek, jelölések deklarációit, valamint feldolgozási utasításokat, megjegyzéseket és paraméteregyed-hivatkozásokat.
Rögtön lássunk egy példát az érthetőség kedvéért:

<?xml version="1.0" encoding="ISO-8859-2"> <!DOCTYPE FORMA1VILAGBAJNOK [ <!ELEMENT FORMA1VILAGBAJNOK (#PCDATA) > <!-- egyetlen eleme deklarácioja --> ] > <FORMA1VILAGBAJNOK>Damon Hill</FORMA1VILAGBAJNOK>

A példában létrehoztunk egy érvényes XML dokumentumot, amely egyetlen elemet tartalmaz mégpedig a dokumentumelemet (FORMA1VILAGBAJNOK), amely csak szöveges tartalommal (#PCDATA) rendelkezhet (parsed charakter data PCDATA = értelmezett szöveges adat)

Elemtípusok deklarációja

Az elemtípusok deklarálásának általános alakja:

<!ELEMENT elemneve tartalomleírás>

ahol elemneve az éppen deklarálni kívánt elem neve (FIGYELJÜNK a kis és nagybetűs eltérésekre), tartalomleírás pedig meghatározza, hogy az elem milyen tartalommal rendelkezhet. Az elemek tartalma a következő lehet:

  • EMPTY - üres elem, tehát sem szöveget, sem gyermekelemeket nem tartalmaz

    <!ELEMENT URES EMPTY>
  • ANY - bármi-nemű tartalom, tehát szöveges, elem, vagy vegyes tartalom (elemtartalom esetén deklarálni kell az egyes gyermekelemeket)

    <!ELEMENT BARMI ANY>
  • elemtartalom, vagyis a deklarációban megadott elemek tartalmazhatja
    <!ELEMENT ELEMTARTALMU (EGYIK_GYERMEKELEM, MASIK_GYERMEKELEM)>

  • vegyes tartalommal rendelkező elemek a szöveges adatokon kívül a deklarált elemeket is tartalmazhatja határozatlan számban

    <!ELEMENT VEGYES (#PCDATA, GYERMEKELEM)*>

Amennyiben az elem gyermekelemeket tartalmaz (elemtartlommal rendelkezik), az összes gyermekelem nevét fel kell tüntetni a szülőelem deklarációjában, majd az egyes gyermekelemeket egyesével deklarálni kell. Mutassunk rá rögtön egy példát:

<?xml version="1.0" encoding="ISO-8859-2"> <!DOCTYPE F1VILAGBAJNOKOK [ <!ELEMENT F1VILAGBAJNOKOK (F1VILAGBAJNOK)*> <!ELEMENT F1VILAGBAJNOK (EV, NEV, NEMZETISEG)> <!ELEMENT EV (#PCDATA)> <!ELEMENT NEV (#PCDATA)> <!ELEMENT NEMZETISEG (#PCDATA)> <!-- egyetlen eleme deklarácioja --> ] > <F1VILAGBAJNOKOK>   <F1VILAGBAJNOK>     <EV>1954</EV>     <NEV>Juan Fangio</NEV>     <NEMZETISEG>Argentin</NEMZETISEG>   </F1VILAGBAJNOK>   ... </F1VILAGBAJNOKOK>

Példánkban létrehoztunk egy DTD-t a forma1 világbajnokait tartalmazó XML fájlunkhoz. A DOCTYPE deficióban ugye meg kell adni a gyökérelem nevét, ami jelen esetben a F1VILAGBAJNOKOK, utána pedig deklarálni kell az egyes elemeket, feltüntetve a tartalmukat.
Elsőként magát a dokumentumelemet kell deklarálni, amely elemtartalmú és egyetlen típusú elemből (F1VILAGBAJNOK) tartalmaz sokat (*). Amennyiben a csillagot (*) elhagynánk, a dokumentumelem csak egy F1VILAGBAJNOK típusú gyermekelemet tartalmazhatna. A használható előfordulást jelző karakterek a következők:

  • ? - nulla vagy egy az előtte álló elemből

  • + - egy vagy több az előtte álló elemből

  • * - nulla vagy több az előtte álló elemből

Következő lépésként deklarálnunk kell a F1VILAGBAJNOK nevű elemet, amely szintén elemtartalmú és az EV, NEV, NEMZETISEG nevű gyermekelemeket fogja tartalmazni a felsorolás sorrendjében (!!!). Mivel nem használtunk semmilyen különleges sokszorozó megjelölést az egyes gyermekelemek felsorolásánál, ezért mindegyiket pontosan egyszer fogja tartalmazni. Az egyes gyermekelemek felsorolásánál, a vessző (",")  vagy ("|") karakterre történő cserélésével, úgymond választólistát hozunk létre, tehát a

<!ELEMENT F1VILAGBAJNOK (EV | NEV | NEMZETISEG)>

deklaráció jelentése: a F1VILAGBAJNOK nevű elemnek tartalmaznia kell vagy egy EV, vagy egy NEV, vagy egy NEMZETISEG  nevű elemet. Az egyes felsorolást elválasztó, illetve előfordulás számát jelző karakterek kombinálásával létrehozhatunk összetett adatstruktúrát és előfordulást.
Vegyes elemet deklaráhatunk, úgy, hogy az elem tartalmánál a #PCDATA-át is felsoroljuk mint lehetséges tartalom, valamint az egyes elemeket vagy karakterral (" |") választjuk el és csillagot teszünk utánna. Így sajnos nem tudjuk korlátozni az egyes elem előfordulási számát és sorrendjét sem. Lássunk ezekre egy konkrét példát:

<?xml version="1.0" encoding="ISO-8859-2"?> <!DOCTYPE EMBEREK [ <!ELEMENT EMBEREK (EMBER)*> <!ELEMENT EMBER (NEV, SZULEV, VEGZETTSEG, (MUNKAHELY | ISKOLA), GYERMEK*)> <!ELEMENT NEV (#PCDATA | KOZEPSONEV)*> <!ELEMENT KOZEPSONEV (#PCDATA)> <!ELEMENT SZULEV (#PCDATA)> <!ELEMENT VEGZETTSEG (#PCDATA)> <!-- egyetlen eleme deklarácioja --> <!ELEMENT MUNKAHELY (#PCDATA)> <!ELEMENT ISKOLA (#PCDATA)> <!ELEMENT GYERMEK (#PCDATA)> ] > <EMBEREK>   <EMBER>     <NEV>Gulyás<KOZEPSONEV>T</KOZEPSONEV>Péter</NEV>     <SZULEV>1970</SZULEV>     <VEGZETTSEG>Technikai egyetem</VEGZETTSEG>     <MUNKAHELY>Paksi atomerőmű</MUNKAHELY>     <GYERMEK>Gujás Veronika</GYERMEK>     <GYERMEK>Gujás Zoltán</GYERMEK>   </EMBER>   <EMBER>     <NEV>Hajmási Péter</NEV>     <SZULEV>1981</SZULEV>     <VEGZETTSEG>Ipari Középiskola</VEGZETTSEG>     <ISKOLA>ELTE</ISKOLA>   </EMBER>   ... </EMBEREK>

A példánkban létrehoztunk egy személy nyilvántartó adatbázist. Az egyes személyek adatait az EMBER nevű elem tartalmazza. Minden ember pontosan egy névvel (NEV), egy születési évvel (SZULEV) és egy végzettséggel (VEGZETTSEG) rendelkezik, amelyet egy munkahely (MUNKAHELY) vagy egy iskola (ISKOLA) követ, attól függően, hogy az illető dolgozik-e vagy tanul. Az adatok sorát a gyermekek (GYERMEK) felsorolása követ, akikből lehet nulla vagy több (*). Az egyes elemek deklarálása ugyanaz, mint az első példában, kivéve a NÉV elemet, mivel ez vegyes tartalmú. Tartalmazza a vezeték illetve keresztnevet, mint szöveges adat (#PCDATA) és a középsőnevet (KOZEPSONEV) mint gyermekelem. Sajnos e gyermekelem előfordulását nem lehet korlátozni, mivel vegyes tartalom deklarálásánál mindig a nulla vagy több (*) előfordulást kell használni.

Jellemzők deklarálása

Az egyes elemekben használt összes jellemzőt deklarálni kell, amely általános formája a következő:

<!ATTLIST ELEMNEV jellemzo_neve jellemzo_tipusa alapertelmezes_deklaracio ...>

Az egyes jellemzők definiálásakor meg kell adni az elem nevét (ELEMNEV), amely jellemzőit éppen definiáljuk, majd az egyes jellemzők deklarációi következnek. Az egyes jellemzők nevét (jellemzo_neve) és típusát (jellemzo_tipusa) a jellemző alapértelmezés deklarációja (alapertelmezes_deklaracio) követi, amely megadja, hogy a jellemző megadása kötelező-e, vagy ha nem akkor esetlegesen egy alapértéket rendeljen hozzá az értelmező. A következő példában bemutatásra kerül, az alapértek adás és egy jellemző megadásának kötelezővé tétele.

<?xml version="1.0" encoding="ISO-8859-2"?> <!DOCTYPE EMBEREK [ <!ELEMENT EMBEREK (EMBER+)> <!ELEMENT EMBER EMPTY> <!ATTLIST EMBER   csaladi_allapot CDATA "igen"   szul_ev CDATA #REQUIRED> <!-- csaladi_allapot megadasa nem kotelezo, ha nem adjuk meg, akkor az alapertek "igen" rendelodik hozza szul_ev megadasa kotelezo, hianya eseten hibat kapunk. --> ] > <EMBEREK>   <EMBER szul_ev="1970" />   <EMBER csaladi_allapot="nem" szul_ev="1999" />   <EMBER csaladi_allapot="igen" szul_ev="1977" /> </EMBEREK>

Az egyes jellemzőknek három típusa lehetséges:

  • karakterlánc - mely tartalma és létrehozása az előző részben ki lett tárgyalva

  • token típus - mely tartalma bizonyos korlátok közé van szorítva

    • ID - ezen jellemző tartalmának egyedi érvényes névnek(előző részben megtalálható az érvényes név definíciója) kell lenni, vagyis két jellemzőnek nem lehet egyforma tartalmú ID típusú jellemzője
      <!ATTLIST EMBER szemelyi_szam ID #REQUIRED> ... <EMBER szemelyi_szam="22022" /> <EMBER szemelyi_szam="18456" /> <EMBER szemelyi_szam="22022" /> <!-- helytelen mivel mar letezik ilyen ID -->
    • IDREF - referencia (mutató) egy már létező ID típusú jellemzőre, tehát értéke csak egy létező ID típusú jellmező értéke lehet
      <!ATTLIST EMBER szemelyi_szam ID #REQUIRED> <!ATTLIST GYERMEK szemelyi_szam ID #REQUIRED szulo_szem_sz IDREF #REQUIRED> ... <EMBER szemelyi_szam="22022" /> <GYERMEK szemelyi_szam="18456" szulo_szem_sz="22022" />
    • IDREFS - ugyanaz, mint az IDREF azzal a különbséggel, hogy egyidejűleg több, már létező azonosítóra hivatkozhatunk egy tulajdonságon belül, úgy, hogy az egyes referenciákat szóközzel választjuk el egymástól
      <!ATTLIST GYERMEK szemelyi_szam ID #REQUIRED szulo_szem_sz IDREFS #REQUIRED> ... <GYERMEK szemelyi_szam="18456" szulo_szem_sz="22022 25183" />
    • NMTOKEN típusú jellemző értéke számok, betűk, pontok, kötőjelek, aláhúzások, vagy kettőspontok (kettőspont nem szerepelhet az első helyen) sorozata.
      <!ATTLIST EMBER csoport_azon NMTOKENS #REQUIRED> ... <EMBER csoport_azon="pd-22-022-si" /> <EMBER csoport_azon="pd-22-022-si" /> <EMBER csoport_azon="tt-56-111-si" /> <EMBER csoport_azon="tt-%56-111-si" /> <!-- helytelen ertekmegadas (%-t nem tartalmazhat) -->
    • NMTOKENS típusú jellemző ugyanaz, mint az NMTOKEN, azzal a különbséggel, hogy egyidejűleg több NMTOKEN típusú értéket adhatunk meg, szóközzel elválasztva
    • ENTITY típusú jellemző értéke egy, a DTDben már deklarált nem értelmezett egyed (egyed foglamával és deklarálásával a későbbiekben fogunk foglalkozni) lehet
    • ENTITIES típusú jellemző ugyanolyan, mint az ENTITY típusú, azzal a különbséggel, hogy értekül adhatunk több nem értelmezett egyeded egyszerre, szóközzel elválasztva
  • felsorolás típusú jellemzőknél megadhatunk egy értékhalmazt, amelyből a végső jellemzőértek kiválasztható. Abban az esteben, ha a  jellmező értéke nem egyezik meg egyik értékkel sem a halmazból, úgy érvénytelenné válik a dokumentum. Az egyes jellemző értékekre ugyanazon feltételek vonatkoznak mint a NMTOKEN típusú jellemzőkre. A jellemzőértkék halmaz elemeit zárójelben "|" karakterrel elválasztva kell megadni. A felsorolás típusú jellemzőknél szintén használhatók az alapértelmezés deklarációk.
    <!ATTLIST EMBER nem (férfi | nő) #REQUIRED> ... <EMBER nem="férfi" /> <EMBER nem="ferfi" /> <!-- helytelen mert "ferfi"nem egyenlő "férfi"-vel -->
Az alapértelmezés deklaráció a következő értékeket veheti fel:
  • #REQUIRED használatakor a jellemző (ami után szerepel) megadása következő.
  • #IMPLIED használatakor a jellemzőt akár elhagyhatjuk, akár megadjuk a dokumentum érvényes lesz.
    <!ATTLIST EMBER nem CDATA #IMLIED> ... <EMBER nem="ferfi" /> <EMBER/>
  • jellemző érték, amelyet akkor kap meg a jellemző, ha nem adunk meg neki más értéket
    <!ATTLIST EMBER nem CDATA "ferfi"> ... <EMBER /> <EMBER nem="ferfi" /><!-- megegyezik a felette levővel --> <EMBER />
  • #FIXED használatakor, ha nem adunk a jellemzőnek értéket, akkor az alapértelmezett értéket kapja meg, viszont, ha adunk értéket, akkor csak az alapértéket adhatjuk meg, másként a dokumentum érvénytelenné válik.
    <!ATTLIST EMBER nem CDATA #FIXED "férfi"> ... <EMBER /> <EMBER nem="férfi" /> <-- ez és a felettelevő egyenértékű --> <EMBER nem="nő" /><!-- helytelen mert csak az alapérték adható meg -->
Névterek használata a DTD-ben

Névterek használata DTDkben nagyon egyszerű, megegyezik a dokumentumokban való használattal, vagyis az egyes elemek illetve jellemzők neve előtt fel kell tüntetni a névteret (amelyhez tartozik) kettősponttal elválasztva. Az egyes névterek DTD deklarálását is fel kell tüntetni az elemben, amelyikben deklaráljuk, mint jellemző. A következő példából remélhetőleg mindenki számára érthetővé válik:

<?xml version="1.0" encoding="ISO-8859-2" ?> <!DOCTYPE EMBEREK [ <!ELEMENT EMBEREK (szulo:EMBER+)> <!ELEMENT szulo:EMBER EMPTY> <!ATTLIST EMBEREK xmlns:szulo CDATA #REQUIRED> <!ATTLIST szulo:EMBER szulo:szul_ev CDATA #IMPLIED> ] > <EMBEREK xmlns:szulo="http://www.prog.hu"> <szulo:EMBER szulo:szul_ev="1985" /> </EMBEREK>

 

Külső és belső DTDk

Azon DTDket, amelyeket az XML dokumentum közvetlenül tartalmaz, nevezzük belső DTD alkészletnek, azokat, amelyekre csak hivatkozás van az XML dokumentumban nevezzük külső DTD alkészletnek. A külső és belső DTD alkészletek együttes használata is lehetséges. A végső DTD a külső és belső DTD uniója lesz. Többszörös deklaráció esetén a belső DTD élvez nagyobb prioritást, tehát felülírja az azonos külső DTD alkészletben szereplő deklarációt. Lássunk egy rövid példát a használatukra:

emberek.dtd

<?xml version="1.0" encoding="ISO-8859-2" ?> <!ELEMENT EMBEREK (EMBER)*> <!ELEMENT EMBER (NEV, SZULEV, VEGZETTSEG, (MUNKAHELY | ISKOLA), GYERMEK*)> <!ELEMENT NEV (#PCDATA | KOZEPSONEV)*> <!ELEMENT KOZEPSONEV (#PCDATA)> <!ELEMENT SZULEV (#PCDATA)> <!ELEMENT VEGZETTSEG (#PCDATA)> <!-- egyetlen eleme deklarácioja --> <!ELEMENT MUNKAHELY (#PCDATA)> <!ELEMENT ISKOLA (#PCDATA)> <!ELEMENT GYERMEK (#PCDATA)>
emberek.xml
<?xml version="1.0" encoding="ISO-8859-2" ?> <!DOCTYPE EMBEREK SYSTEM "emberek.dtd" [ <!ATTLIST GYERMEK szul_ev CDATA #IMPLIED> ] > <EMBEREK>   <EMBER>     <NEV>Gulyás<KOZEPSONEV>T</KOZEPSONEV>Péter</NEV>     <SZULEV>1970</SZULEV>     <VEGZETTSEG>Technikai egyetem</VEGZETTSEG>     <MUNKAHELY>Paksi atomerőmű</MUNKAHELY>     <GYERMEK  szul_ev="1990">Gujás Veronika</GYERMEK>     <GYERMEK  szul_ev="1990">Gujás Zoltán</GYERMEK>   </EMBER>   <EMBER>     <NEV>Hajmási Péter</NEV>     <SZULEV>1981</SZULEV>     <VEGZETTSEG>Ipari Középiskola</VEGZETTSEG>     <ISKOLA>ELTE</ISKOLA>   </EMBER>   ... </EMBEREK>

Amint az a példából is látszik a külső DTDben deklaráltuk a dokumentum szerkezetét, viszont a GYERMEK elem szul_ev jellemzőjét a belső DTDben. A végső DTD pedig a külső és belső uniója ezért használhatjuk a szul_ev jellemzőt dokumentumban.

Egyedek deklarálása és használata

Az egyedek az XMLben, mint konstansok működnek, vagyis azokat az adatokat (elemek, jellemzők, DTDk), amelyeket gyakran használunk egyedek segítségével beilleszthetjük a dokumentumba ahányszor csak akarjuk és így egyben a dokumentum méretét is csökkenthetjük. Esetleges változások esetén elegendő magát az egyed deklarációt megváltoztatni. Az egyedeket a dokumentum DTDjében kell deklárálni és a következő fajtái lehetnek:

  • általános egyedek - tartalmazhatnak bármilyen XML vagy nem XML típusú adatot
    • értelmezett egyedek - tartalmazhatnak bármilyen XML típusú adatot
      • belső értelmezett egyedek deklarációjának általános formája:
        <!ENTITY nev ertek>
        ahol név az egyed neve, melynek érvényesnek kell lenni és amivel a dokumentumban fogunk rá hivatkozni, az érték pedig az, amit értékül adunk az egyednek, és amit beilleszt a fordító arra a helyre, ahol hivatkoztunk rá (az egyed nevével). Egy rövid példán szeretném bemutatni a használatát:
        <?xml version="1.0" encoding="ISO-8859-2" ?> <!DOCTYPE EMBEREK [ <!ENTITY f "ferfi"> <!ENTITY n "no"> <!ENTITY nev "Michael<KOZEPSONEV>J</KOZEPSONEV>Fox"> <!ELEMENT EMBEREK (EMBER*)> <!ELEMENT EMBER (#PCDATA | KOZEPSONEV)*> <!ELEMENT KOZEPSONEV (#PCDATA)> <!ATTLIST EMBER nem CDATA #REQUIRED> ] > <EMBEREK>   <EMBER nem="&f;">&nev;</EMBER>   <EMBER nem="ferfi">Michael<KOZEPSONEV>J</KOZEPSONEV>Fox</EMBER> </EMBEREK>  
        A fenti példában létrehoztunk egy f, egy n és egy nev nevű egyedet, majd ezeket beillesztettük a dokumentumba. A két EMBER típusú elem tartalma teljesen megegyezik.
      • külső általános értelmezett egyedek annyiban különböznek a belső általános értelmezett egyedektől, hogy az egyedek tartalma külső fáljban van elhelyezve. A általános deklaráció formája:
        <!ENTITY nev SYSTEM erőforrás>
        ahol, nev az egyed neve, amivel hivatkozni fogunk rá, az erőforrás pedig a fájl elérési útja (URI). Most lássuk az előző példánkat külső általános egyed segítségével:

        nev.xml
        Michael<KOZEPSONEV>J</KOZEPSONEV>Fox

        emberek.xml

        <!DOCTYPE EMBEREK [ <!ENTITY f "ferfi"> <!ENTITY n "no"> <!ENTITY nev SYSTEM "nev.xml"> <!ELEMENT EMBEREK (EMBER*)> <!ELEMENT EMBER (#PCDATA | KOZEPSONEV)*> <!ELEMENT KOZEPSONEV (#PCDATA)> <!ATTLIST EMBER nem CDATA #REQUIRED> ] > <EMBEREK>   <EMBER nem="&f;">&nev;</EMBER>   <EMBER nem="ferfi">Michael<KOZEPSONEV>J</KOZEPSONEV>Fox</EMBER> </EMBEREK>
    • nem értelmezett egyedek - tartalmazhatnak bármilyen nem XML típusú adatot. Az egyedeket egy ENTITY vagy ENTITIES típusú jellemzőhöz rendelhetjük hozzá, viszont az értelmezett egyedektől eltérően az értelmező nem illeszti be a külső fájl tartalmát, csupán átadja a feldolgozó programnak az (külső fájl) URI-jét és leírását (vagy a feldolgozó program elérhetőség). Az általános nem értlemezett egyedek csak külső fájlokra mutathatnak.
      • külső nem értelmezett egyedek általános deklarációja:
        <!NOTATION jelölésnév SYSTEM erőforrás>
        <!ENTITY egyednév SYSTEM erőforrás NDATA jelölésnév>

        Ahol jelölésnév a jelölés neve, amellyel hivatkozni fogunk rá, az erőforrás a leírt külső nem értelmezett egyedet feldolgozó program URIja, vagy a külső nem értelmezett egyed leírása.
        Az egyednév az egyed neve, amivel hivatkozni fogunk rá, az erőforrás a külső fájl (amelyet be akarunk illeszteni a dokumentumba) URIja, jelölésnév pedig a DTDben deklarált NOTATION típusú elem (jelölés) neve. Az érthetőség kedvéért lássunk egy rövid példát:
        <!DOCTYPE EMBEREK [ <!NOTATION JPG SYSTEM "acdsee.exe"> <!ENTITY fenykepem SYSTEM "enkepem.jpg" NDATA JPG> <!ELEMENT EMBEREK (EMBER*)> <!ELEMENT EMBER (#PCDATA)> <!ATTLIST EMBER fenykep ENTITY #IMPLIED> ] > <EMBEREK>   <EMBER fenykep="fenykepem">Izsák Péter</EMBER> </EMBEREK>
        Tehát a példánkban létrehoztunk egy grafikus adatokat leíró jelölést (JPG), amely a feldolgozónak átadja a acdsee.exe szoftver elérési útvonalát, amely segítségével a kép megjelenítésre kerül. Ezután létrehoztuk az általános nem értelemezett külső egyedet, melyhez hozzárendeltük a kép erőforrását, majd az EMBER elemnek deklaráltunk egy fénykép jellemzőt, amely nem értelmezett adatot (külső nem értelmezett egyedet) fog tartalmazni. Végül az EMBER elem létrehozásakor hozzárendeltük a fénykép jellemzőhöz a nem értelmezett külső egyedet.
  • paraméter egyedek DTDket tartalmaznak, melyek mindig értelmezettek
    • értelmezett
      • belső paraméteregyedeket a következő képpen kell deklarálni:
        <!ENTITY % név érték>
        ahol név az egyed neve, melynek érvényes kell lenni, érték pedig a jellemző értéke (tehát maga a DTD deklarációk összessége) szimpla vagy dupla idézőjelek között. Figyeljünk arra, hogy a határoló idézőjelek nem szerepelhetnek az egyed értékében.
        <!DOCTYPE EMBEREK [ <!ENTITY % ember "       <!ELEMENT EMBEREK (EMBER*)>       <!ELEMENT EMBER (#PCDATA)>" > %ember; <!ATTLIST EMBER nem (ferfi | no) #REQUIRED> ] > <EMBEREK>   <EMBER nem="ferfi">Izsák Péter</EMBER> </EMBEREK>
        A példaprogramunkban létrehoztunk egy ember nevű belső paraméteregyedet, majd beillesztettük a DTDbe.
      • külső paraméteregyedek csak abban különböznek a belső paraméteregyedektől, hogy a külső paraméteregyed egy külső fájlban levő jelőlésdeklarációkat illeszt be a kívánt helyre. A külső fájl tartalmazhat elem, jelölés és egyeddeklarációt, feldolgozási utasításokat és megjegyzéseket. Deklaráció általános alakja:

        <!ENTITY % név SYSTEM erőforrás>
        ahol név az egyed neve, amivel hivatkozni fogunk rá, erőforrás pedig a külső fájl elérési útvonala.

Karakterhivatkozások

Karakerthivatkozások segítségével beszúrhatunk olyan karaktereket, amelyeket normál állapotban nem, estleg nem tartalmazza a billentyűzetünk. A karakterhivatkozásokat nem kell előre deklarálni, pusztán az engedélyezett módon beilleszteni arra a helyre, ahová akarjuk. Ezen karakterbeillesztési módok sokaknak ismerősek lesznek a HTMLből. A karakterhivatkozás általános megadása:

  1. &#decimális_szám;   példa: &#33; - felkiáltó jel, &#38; - és jel(&)
  2. &#xhexadecimális_szám;   példa: &#x21; - felkiáltó jel, &#x26; - és jel(&)
A bemutatott megoldásokon kívül létezik egy harmadik megoldás, mégpedig általános értelmezett egyedek segítségével. Léteznek előre definiált általános értelmezett egyedek, de lehetőség van saját deklarációra is:
egyed karakterhivatkozás karakter
&amp; &#38; &
&lt; &#60; <
&gt; &#62; >
&apos; &#39; '
&quot; &#34; "

<!ENTITY sajatBetu "&#189;">

Ezzel a módszerrel kissé emberközelibbé válik az egyes karakterek beillesztése, mivel a különböző számkombinációk helyett neveket használhatunk. Karakterhivatkozások beilleszthetőek az egyes elemek szöveges tartalmába, jellemzők értékeibe, vagy egyedek értékeibe egyaránt.

Lehet, hogy első látásra nagyon bonyolultnak és soknak tűnik a DTDk használata, de a kihasználtságát tekintve megéri megtanulni. Ajánlom ezen rész többszöri átolvasását, valamint a cikkben bemutatott rövidke példák átnézését esetleg kibővítését, amely segítségével egy kis gyakorlatra is szert teszünk a sokszor bonyolultnak tűnő DTDk írásában. A következő részben megismerkedünk az érvényes dokumentumok létrehozásának másik módjával, mégpedig az XML sémával.