A cikksorozat ezen részében felfrissítjük és kibővítjük az előző részben már megemlített XML dokumentum létrehozására vonatkozó szabályokat. Első lépésként definiáljunk pár fontos fogalmat, melyet a cikkben használni fogunk:

  • Jólformázott XML dokumentumnak nevezzük az összes olyan dokumentumot, amelyek teljes egészében megfelelnek az XML specifikációban meghatározott szabályoknak. Ezen szabályokból viszonylag kevés van, ezért betartásuk illetve megjegyzésük nem okoz nagy problémát. Az Internet Explorer XML értelmező modulja értelmezés előtt végrehajt jólformázottsági ellenőrzést, és végzetes hibával tér vissza, ha nem felel meg ennek a dokumentum.
  • Érvényes névnek (elemnév, tulajdonságnév ...) nevezzük azokat a karaktersorozatokat, amelyek betűvel vagy alulvonással kezdődnek, amit tetszőleges hosszúságú szám, betű, pont, alulvonás vagy kötőjel követ. Kivételt képez ez alól az "xml" karaktersorozat bármilyen kis és nagybetűs kombinációja, amely az XML számára foglalt (az IE nem végez e téren hibaellenőrzést, mégis kerülendő a használata). Érvényes névnek számítanak: _valami, he5l88, _._55kl
  • Jelentés nélküli karaktereknek nevezzük azon karaktereket, melyeket az XML értelmező modul figyelmen kívül hagy, vagyis nem befolyásolja a dokumentum tartalmát, pusztán az áttekinthetőség növelését szolgálja. Ezen karakterek közé soroljuk a szóközöket, tabulátorokat, sortöréseket.

Most nézzük meg kicsit részletesebben egy érvényes XML dokumentum felépítését, illetve az egyes elemek, részek lehetséges tartalmát:

  • fejrész
    • XML fejléc
    • dokumentum típus definíció
    • XML-séma definíció
    • megjegyzések
    • feldolgozási utasítások(stíluslap definíció vagy egyéb)
    • jelentés néküli karakterek
  • test rész
    • dokumentum elem
      • további elemek
      • megjegyzések
      • feldolgozási utasítások
      • jelentés nélküli karakterek
    • jelentés néklüli karakterek
    • megjegyzések
    • feldolgozási utasítások
XML fejléc (deklaráció)

Az XML fejléc megadása ugyan nem kötelező, az XML specifikáció mégis előírja a használatát. Az XML fejlécnek - ha létezik - mindig az XML dokumentum első sorában kell szerepelnie, nem előzheti semmilyen jelentés nélküli karakter. A fejléc amellett, hogy azonosítja a dokumentumot mint XML dokumentum, pár fontos információval is ellátja a feldolgozó szoftvermodult.

<?xml version="1.0" encoding="ISO-8859-2" standalone="yes"?>

Amint azt láthatjuk, az XML fejléc egy speciális feldolgozási utasítás (feldogozási utasításokat a későbbiekben fogjuk tárgyalni), amely tartalmazza az XML verziószámot (version="1.0"), kódolási formát (encoding="ISO-8859-2") és hogy tartozik-e a dokumentumhoz külső jelölésdeklaráció (standalone="yes").

Az egyes tulajdonságok értékeit megadhatjuk szimpla (') illetve dupla (") idézőjel között egyaránt. Abban az esetben, ha az XML fejlécben szerepel az encoding tulajdonság, annak mindig a standalone tulajdonság előtt kell lenni.

Az XML dokumentumokban használhatjuk az összes unicode karaktert (tartalmazza a világ összes nyelvének betűit), melyeket különböző képpen lehet kódolni. Az XML feldolgozó alapállapotban feltételezi, hogy UTF-8-as (nem fix hosszú kódolás, bővebben itt) vagy UTF-16-os (16 bites kódolás) kódolást használunk. Amennyiben más kódolást szeretnénk használni, úgy azt tudatni kell az XML feldolgozóval. Erre szolgál az encoding tulajdonság. Jelen esetben az ISO-8859-2 kódolást használjuk, amely 8 biten kódolja a karaktereket és többek között tartalmazza az összes magyar ékezetes karaktert. Használhatnánk nyugodtan az UTF-8 illetve UTF-16-os kódolásokat is, de mivel mi csakis a standard ASCII és a magyar ékezetes karaktereket fogunk használni, így nekünk elegendő a ISO-8859-2 kódolás is.

A standalone tulajdonság megadásával tudatjuk az XML feldolgozó modullal, hogy a dokumentum tartalmazni fog külső jelölésdeklarációt (standalone="no"), és hibajelzést ad, ha mégsem talál ilyet a dokumentumban, viszont mi deklaráltuk. Ellenkező esetben (standalone="yes") a fordító modul tudtára adjuk, hogy nyugodtan fordíthatja a dokumentumot, mivel az nem tartalmaz semmi olyan jelölésdeklarációt, amely befolyásolná a dokumentum tartalmát.

Dokumentum típus definíció és a XML-séma definíció

Ezek speciális, az XML dokumentumok típusának leírását szolgáló "nyelvek". (Azért raktam idézőjelbe a nyelveket, mert a dokumentum típus definíció külön szintaktikát használ, ellenben az XML sémával, melynek szintaktikája megegyezik az XML-ével). Ezen "nyelvek" segítségével pontosan meghatározhatjuk egy XML dokumentum felépítését, az egyes elemek elhelyezkedését illetve azok tartalmát. A dokumentumok típusát leíró nyelvekkel részletesen a cikksorozat következő részében ismerkedünk meg.

Megjegyzések

Az összes programnyelvben létezik egy vagy több karakter-kombináció, amely által határolt szöveget a forító egyáltalán nem értelmez vagy nem értelmezi forráskódként. Ezeket nevezzük megjegyzéseknek. A megjegyzések célja a forráskód olvashatóságának és érthetőségének a növelése. Az XML specifikáció is definiál megjegyzések létrehozásához szükséges karaktersorozatot. Egy megjegyzés általános formája:

<!-- Ez az első & egyben bemutató célú megjegyzés  -->

Ahogy az a bemutató példából is kiderül a megjegyzés a "<!--" karakterkombinációval kezdődik és a "-->" karakterkombinációval záródik. A nyitó és záró karakterkombináció közé bármilyen karaktert beszúrhatunk, kivéve a dupla kötőjelet " --" és a megjegyzés utolsó karaktereként a szimpla kötőjelet "-", mivel ilyenkor a "--->" kombinációt kapnánk, amely helytelen.
A megjegyzéseket bárhová beilleszthetjük az XML dokumentumba, kivéve más jelöléseken belülre. Most lássunk pár példát:

<?xml version="1.0" encoding="ISO-8859-2"  standalone="yes"?> <!--érvényes megjegyzés --> <F1VILAGBAJNOKOK <!--érvényTELEN megjegyzés --> > <!--érvényes megjegyzés -->
    <F1VILAGBAJNOK>        <EV>1954</EV> <!--érvényes megjegyzés -->        <NEV>Juan Fangio<!--érvényes megjegyzés --></NEV>        <NEMZETISEG>Argentin</NEMZETISEG>     </F1VILAGBAJNOK> <F1VILAGBAJNOKOK> <!--érvényes megjegyzés -->
Feldolgozási utasítások

Egy speciális jelölőelem típus, amely a dokumentum adattartalmán kívül tartalmaz információkat a feldolgozó alkalmazás számára. Tehát maga az XML értelmező modul nem törődik a feldolgozási utasításokkal, csupán továbbadja azokat a feldolgozó alkalmazásnak. A feldolgozási utasítás formája:

<?cel_szoftver <paraméter(ek)>  ?>

A feldolgozási utasítás nyitó elemét "<?" rögtön a cél alkalmazás (amelynek a paraméterek át lesznek adva) neve követ, amelynek érvényesnek kell lenni (lásd az érvényes név definícióját feljebb). A cél alkalmazás neve és a nyitó karakter között nem szerepelhet semmilyen más jelentés nélküli karakter. Ezt követik az egyes paraméterek, amelyek a zárókrakteren ("?>") kívül bármilyen más karaktert tartalmazhatnak.

A feldolgozási utasításoknak általánosan két fajtájuk létezik:

  1. szabványos feldolgozási utasítások, amelyeket a szabványos XML feldolgozóknak tudniuk kell értelmezni. Ilyen például a megjelenítési utasítás lépcsős stíluslappal:
    <?xml-stylesheet type="text/css" href="f1vilagbajnokok.css"?>
  2. egyéni feldolgozó szoftverek számára létrehozott feldolgozási utasítások, amelyeket az általunk létrehozott feldolgozó szoftver (szkript) értelmez:
    <?sajat_szoft param1="ertek1" ?>

A feldolgozási utasítások elhelyezésére ugyanazon szabályok vonatkoznak, mint a megjegyzések elhelyezésére.

Elemek létrehozása

Mivel az XML dokumentumok tényleges adattartalmát az egyes elemek hordozzák, ezért a hangsúly ezen elemeken van. Az elemnevek kis és nagybetűre érzékenyek, ezért figyelni kell arra, hogy a kezdő illetve záró részek egyformák legyenek ("elemnev" és "ElemNev" nem egyezik!!!). Az elemek általános formája:

<ELEMNEV [tulajdonság="ertek"] > tartalom </ELEMNEV>

Minden elemnek (kivéve az üres elemeket, amelyekről kicsit később lesz szó) rendelkeznie kell nyitó illetve záró résszel. Az elemnevet a "<" és a ">" közé helyezzük. A záró elemrész a "/"-al különbözik a nyitó résztől, amelyel jelezzük az elem végét (sokak számára jól ismert megoldás a HTML-ből). Az elemnévnek érvényesnek kell lenni (lásd feljebb az érvényes elemek definícióját)!

Minden elem (ha nem szabjuk meg másként pl. dokumentum típus definícióval vagy XML-sémával) rendelkezhet szöveges tartalommal, elemtartalommal (újabb elemeket tartalmaz), illetve vegyes (szöveg és elem tartalom egyben) tartalommal.

Az egyes elemek szöveges tartalma lehet tetszőleges hosszúságú karakterlánc, amely nem tartalmaz "&" és "<" karaktereket. A tiltott elemek használatát lehetővé teszik a CDATA részek, illetve karakterhivatkozások használata (ezen megoldásokkal kicsit később ismerkedünk meg).

Az egyes elemek elemtartalma annyit jelent, hogy az egyik elemet beágyazzuk egy másikba. A beágyazott elemeket gyermekelemnek, az őket tartalmazó elemet pedig szülőelemnek nevezzük.
A beágyazott elemek létrehozásának talán az egyik legfontosabb szabálya az, hogy az elemek nem keresztezhetik egymást (ugye a HTMLre ez nem igaz), vagyis:

<szuloelem>   <gyermekkelem> </szuloelem>     gyermek szoveges tartalma   </gyermekelem> <!-- helytelen megoldás --> <szuloelem><gyermekelem>gyermek szoveges tartalma</gyermekelem></szuloelem>  <!-- helyes megoldás -->

Vegyes tartalmú elemek létrehozásakor annyi a teendő, hogy összekombináljuk a szöveges tartalmat az elemtartalommal, így az elemünk szöveg és elemtartalmú is lesz egyben, vagyis:

<szuloelem>    szülő szöveges tartalma    <gyermekelem>gyermek szöveges tartalma</gyermekelem> </szuloelem>

Az egyes elemeknek a tartalmukon kívül lehetnek tulajdonságaik (jellemző) és azoknak értékeik. Az elemtulajdonság általános formája:

<elemnev tulajdonsag="ertek" [tulajdonsag="ertek"]>

A tulajdoságokban, illetve azok értékeiben tárolhatjuk, azon adatokat, amelyeket nem akarunk feltétlenül megjeleníteni. A mi forma1 világbajonokokat tároló példánkban tulajdonságban tárolhatnánk a világbajnok pilóta csapatát.

<F1VILAGBAJNOK csapat="ferrari">     <EV>2002</EV>     <NEV>Michael Schumacher</NEV>     <NEMZETISEG>Nemet</NEMZETISEG> </F1VILAGBAJNOK>

Az egyes jellemzőket az elem nyitórészében adhatjuk meg az elemnév után. A jellemzőnévnek érvényesnek kell lenni, és a hozzá tartozó értéket dupla (") vagy szimpla (') idézőjelben kell megadni. A jellemző értéke tartalmazhat egyed, illetve karakter hivatkozást (egyed, illetve karakter hivatkozásokkal a későbbiekben fogunk foglalkozni) és bármilyen karaktert a határoló karakteren (" ') és "&" karakteren kívül. A tulajdonság értéke "&" karaktert tartalmazhat abban az esetben, ha az egy egyed, illetve karakter hivatkozás elején szerepel. Lássunk pár példát:

<F1VILAGBAJNOK csapat=""ferrari""> <!-- helytelen, mert nem tartalmazhat határoló karaktert--> <F1VILAGBAJNOK csapat='"ferrari"'> <!-- helyes, mert a határoló karakter a ' --> <F1VILAGBAJNOK csapat="ferrari&Schumacher"> <!-- helytelen, mert nem tartalmazhat & karaktert--> <F1VILAGBAJNOK csapat="ferrari&amp;Schumacher"> <!-- helyes, mert &amp; karakterhivatkozás-->

Egy elemen és egy névtéren belül nem lehet két azonos nevű tulajdonság, vagy ha mégis, akkor az első lesz az érvényes a többit figyelmen kívül hagyja az értelmező!

A tulajdonságok használatának nagy előnye, hogy dokumenum típus definíció vagy XML-séma segítségével meghatározhatjuk pontos típusát, valamint egy tartalomhalmaz hozzárendelésével csupán az általunk megengedett értéket veheti fel. Az egyes tulajdonságoknak dokumentum típus definíció vagy XML-séma segítségével alapértéket is megadhatunk, amit akkor vesz fel a tulajdonság, ha nem adunk meg neki értéket (ezen megoldásokkal a későbbi fejezetekben foglalkozunk).

Léteznek továbbá tartalom nélküli elemek, az úgynevezett üres elemek. Ezen elemtípusok a HTML-ből már jól ismertek pl. <IMG> (kép beillesztése), <BR> (sortörés), <HR> (vízszintes vonal). Ha jobban megnézzük a HTML-ből felsorolt elemeket, láthatjuk, hogy az összes elem megjelenítéssel kapcsolatos információt tárol. Nincs ez másként az XML-nél sem, ugyanis az üres elemnek csak tulajdonságai lehetnek, amelyek általában nem megjelenítésre váró információk, hanem inkább megjelenítési információk. Mivel ezen elemtípusnak nincs záróeleme a nyitóelemet a "/>" karaktersorral zárjuk:

<kep forras="valami.jpg" szelesseg="356" magassag="356" />
Dokumentumelem (gyökérelem)

Dokumentum elemnek nevezzük az XML dokumentum adattartalmának legfelső szintű elemét. Egy jólformázott XML dokumentum mindig egyetlenegy legfelső szintű elemet tartalmaz. A dokumentum elem létrehozására ugyanazok a szabályok vonatkoznak mint a többi elemre.
Példák:

<?xml version="1.0" encoding="ISO-8859-2"?> <DOKUMENTUMELEM>   valami szoveg   <VALAMIELEM>valami szoveg</VALAMIELEM> </DOKUMENTUMELEM> <!-- jólformázott dokumentum --> <?xml version="1.0" encoding="ISO-8859-2"?> <VALAMIELEM>valami szoveg</VALAMIELEM> <VALAMIELEM2>valami szoveg</VALAMIELEM2> <!-- érvénytelen dokumentum, mert két legfelső szintű elemet tartalmaz --> <?xml version="1.0" encoding="ISO-8859-2"?> <VALAMIELEM>valami szoveg</VALAMIELEM> <!-- érvényes és egyben a legrövidebb XML dokumentum -->
Névterek

A névterek az egyes elemek, illetve azok tulajdonságainak csoportosítását teszik lehetővé. Rögtön szemléltessük egy példán:
A forma1 világbajnokait tartalmazó XML fájlunkat kicsit átalakítottuk és összevontuk a konstruktőri világbajnokok listájával a következő képpen:

<?xml version="1.0" encoding="ISO-8859-2"?> <F1VILAGBAJNOKSAG>   <IDENY>     <EV>1999</EV>     <NEV>Mika Hakkinen</NEV>     <NEMZETISEG>Finn</NEMZETISEG>   </IDENY>   <IDENY>     <EV>2003</EV>     <NEV>Michael Schumacher</NEV>     <NEMZETISEG>Nemet</NEMZETISEG>   </IDENY>   <IDENY>     <EV>1999</EV>     <NEV>McLaren-Mercedes</NEV>     <NEMZETISEG>Brit</NEMZETISEG>   </IDENY>   <IDENY>     <EV>2003</EV>     <NEV>Ferrari</NEV>     <NEMZETISEG>Olasz</NEMZETISEG>   </IDENY> </F1VILAGBAJNOKSAG>

Ha jobban szemügyre vesszük az XML fájlunkat, látjuk, hogy a konstruktőr világbajnoki címeket tartalmazó elemek ugyanazon elemneveket és ugyanazt a felépítést használja, mint a pilótavilágbajonokok. Ilyen esetben nehézkesen tudná feldolgozó programunk szétválogatni az egyes konstruktőri és egyéni világbajnokok adatait. Ilyen és ehhez hasonló helyzetekben nyújt nagy segítséget a névterek használata.

<?xml version="1.0" encoding="ISO-8859-2"?> <F1VILAGBAJNOKSAG      xmlns:pilota="http://www.prog.hu/pilotak"      xmlns:auto="http://www.prog.hu/autok">   <pilota:IDENY>     <pilota:EV>1999</pilota:EV>     <pilota:NEV>Mika Hakkinen</pilota:NEV>     <pilota:NEMZETISEG>Finn</pilota:NEMZETISEG>   </pilota:IDENY>   <pilota:IDENY>     <pilota:EV>2003</pilota:EV>     <pilota:NEV>Michael Schumacher</pilota:NEV>     <pilota:NEMZETISEG>Nemet</pilota:NEMZETISEG>   </pilota:IDENY>   <auto:IDENY>     <auto:EV>1999</auto:EV>     <auto:NEV>McLaren-Mercedes</auto:NEV>     <auto:NEMZETISEG>Brit</auto:NEMZETISEG>   </auto:IDENY>   <auto:IDENY>     <auto:EV>2003</auto:EV>     <auto:NEV>Ferrari</auto:NEV>     <auto:NEMZETISEG>Olasz</auto:NEMZETISEG>   </auto:IDENY> </F1VILAGBAJNOKSAG>

A névtereket használat előtt definiálni kell, azon elem nyitó részében ahol használni szeretnénk. Az xmlns kulcsszó után adjuk meg a névtér nevét (névtér előtag) valamint a névteret, amely valójában azonosítja a névteret. Névtérnek megadhatunk bármilyen URIt (tehát URL és URN egyaránt használható), amelyet nem kell konkrétan megnyitni vagy elérni az XML dokumentumnak, csupán azonosítja azt.

A névtér előtagot használjuk a dokumentumban, mint névtér azonosító, amelynek megadhatunk tetszés szerinti érvényes nevet. Az egyes névtereket a nyitóelemek, záróelemek illetve tulajdonságnevek előtt egyaránt megadhatjuk kettősponttal elválasztva.

A példánkban a dokumentumelemben definiáltunk két névteret (pilota,auto), amelyeket hozzárendeltünk az egyes elemekhez aszerint, hogy az pilóta vagy konstruktőr világbajnok adatait tartalmazzák.

Az egyes elemknél megadhatunk alapértelmezett névteret, amely az összes felül nem bírált gyermekelemre érvényes, vagyis azon elemekre, amelyeknél nem definiáltunk újabb névtereket. Itt figyelembe kell venni, hogy az alapértelmezett névterek nem vonatkoznak az egyes elemek tulajdonságaira, ezért a tulajdonságoknál külön meg kell adni, hogy melyik névtérhez tartozik.

<?xml version="1.0" encoding="ISO-8859-2"?> <F1VILAGBAJNOKSAG      xmlns="http://www.prog.hu/pilotak"      xmlns:auto="http://www.prog.hu/autok" auto:pilotakat_is_tartalmaz="igen">   <IDENY>     <EV>1999</EV>     <NEV>Mika Hakkinen</NEV>     <NEMZETISEG>Finn</NEMZETISEG>   </IDENY>   <IDENY>     <EV>2003</EV>     <NEV>Michael Schumacher</NEV>     <NEMZETISEG>Nemet</NEMZETISEG>   </IDENY>   <auto:IDENY>     <auto:EV>1999</auto:EV>     <auto:NEV>McLaren-Mercedes</auto:NEV>     <auto:NEMZETISEG>Brit</auto:NEMZETISEG>   </auto:IDENY>   <auto:IDENY>     <auto:EV>2003</auto:EV>     <auto:NEV>Ferrari</auto:NEV>     <auto:NEMZETISEG>Olasz</auto:NEMZETISEG>   </auto:IDENY>

A példaprogramunkban alapértelmezett névtérnek megadtuk a pilotákat, a konsturkőr világbajnokok adatainál viszont felülbíráltuk az alapértelmezett névteret az autó névtérrel. Másik említésre méltó változás a dokumentumelemben szereplő auto névtérhez tartozó pilotakat_is_tartalmaz tulajdonság. Ezen tulajdonság láttán megfogalmazható a következő szabály: névtereket már abban az elemben is használhatjuk, melyben azt deklaráljuk.

Üres alapértelmezett névteret deklarálhatunk úgy, ha semmit sem rendelünk az egyes névtérhez, vagyis:

<F1VILAGBAJNOKSAG xmlns=""> ... </F1VILAGBAJNOKSAG>
CDATA részek

Ahogy azt már említettem, az egyes elemek szöveges tartalma nem tartalmazhat & illetve < karaktereket. Ezen szabályok alól jelent kibúvót a CDATA részek használata. A CDATA rész szöveges tartalmát az XML értelmező puszta szövegként értelmezi, így azon belül sem megjegyzés sem más utasítás nem kerül értelmezésre.
A CDATA rész a "<![CDATA[" karaktersorozattal kezdődik, amelyet bármilyen karaktersorozat követhet kivéve a zárókaraktersorozatot, amely a "]]>" karakterek sorozata.
A CDATA részeket bárhová beilleszthetük, ahová szöveges tartalom beilleszthető. Végezetül lássunk egy példát:

<deklaralas>   <![CDATA[     valtozo deklaralas& inicializalas: <tipus> <valtozo>(=<kifejezes>)(, <valtozo>=<kifejezes2>...);   ]]> </deklaralas>

A cikksorozat ezen részét ajánlom többször is átolvasni, mivel az itt leírt és elmagyarázott megoldásokra fognak épülni a következő részek. Az alapoknál levő esetleges hiányosságok a bonyolultabb dolgok nemértéséhez fognak vezetni. A következő részében az érvényes XML dokumentumok létrehozását fogjuk megtanulni dokumentum típus definíció és XML-séma segítségével.