A dokumentum tervezés minden bizonnyal nem az a témakör, amit mindösszesen egy rövid bekezdésbe össze lehetne foglalni. Mint ilyen, három alapvető jellemzőre fogunk koncentrálni a dokumentum tervezés témakörében:
Leíró és adat-orientált dokumentum szerkezetek:
Ez a két dokumentum stílus adja az XML dokumentumok döntő többségét. Ebben a fejezetben ennek a két stílusnak a jellemzőit fogjuk vizsgálni, illetve azt, hogy mikor melyiket használjuk.
Építő elemek: attribútumok, elemek és karakter adatok. Mivel sok más jellemzője van egy XML dokumentumnak, kevés olyan akad, amelynek hatása lenne a dizájnra, olvashatóságra és az értelmezhetőségre, de ez a fent említett három képes erre.
Buktatók: Az adat modellezés egy hatalmas témakör, olyannyira, hogy egy külön könyvet meg lehetne tölteni vele. Így, ahelyett, hogy mindenre kitérnénk, megpróbálunk azokra a buktatókra koncentrálni, amelyek komoly problémákat jelenthetnek a dokumentumunk használatánál.
Az XML dokumentumokat általában kétféle adatmodellezésre használják. A leíró dokumentumstruktúra az XML tartalmat már létező, szöveg alapú adatok kiegészítésére használja, hasonlóan ahhoz, ahogy a HTML címkéket weboldalaknál. Adat-orientált dokumentumszerkezeteknél az XML tartalom maga a fontos adat. Ebben a fejezetben ezt a két stílust fogjuk vizsgálni, és átnézünk pár példát arra, hogy mikor melyiket célszerű használnunk.
Használjunk adat-orientált dokumentum szerkezeteket jól strukturált adatok modellezéséhez
Ahogy korábban már említettük, az adat-orientált dokumentum struktúra az, amelyben az XML tartalom közvetlenül írja le az adatokat a dokumentumban, más szóval az XML jelölő a számunkra fontos adat a dokumentumban. Emlékezzünk vissza a kórházi betegágy leíró XML egy darabjára.
<?xml version="1.0" encoding="utf-8"?> <account:persons xmlns:information="http://example.org/information" xmlns:account="http://example.org/schema/person"> <account:person> <name>Teszt Elek</name> <age>23</age> <account:favourite> <number>4</number> <dish>Sultkrumpli</dish> </account:favourite> <account:favouriteWebPage> <account:address>http://www.w3.org</account:address> </account:favouriteWebPage> </account:person> </account:persons>
Ez a dokumentum az XML-t arra használja, hogy egy személy jellemzőit adja meg. Itt a szöveg tartalom (másnéven az értelmezett karakter adat, vagy csak karakter adat, ezeket a fogalmakat felcserélhetően fogjuk használni) a dokumentumban értelmetlen az XML címkék nélkül. Akár így is írhattuk volna:
<?xml version="1.0" encoding="utf-8"?> <account:persons xmlns:information="http://example.org/information" xmlns:account="http://example.org/schema/person"> <account:person name="Teszt Elek" age="23"> <account:favourite number="4" dish="Sultkrumpli"/> <account:favouriteWebPage address="http://www.w3.org" /> </account:person> </account:persons>
Ez a dokumentum ugyanazt az adatsort rögzíti, mint az első, de ahelyett hogy karakteradatokat használna az értékek megadására, attribútumokat használ. Ebben az esetben egyáltalán nincsen karakteradat és világos, hogy az XML tartalom maga az adat a dokumentumban. Ha el akarnánk távolítani az XML tartalmat, a dokumentum a szóköztől eltekintve üres lenne. Ez a dokumentumstílus nem az, amit mi ajánlanánk a gyakorlatban, most csak az összehasonlítás célját szolgálja.
A gondolatmenetet tovább is folytathatnánk, hogy az összes tartalmat a person elem attribútumai közé visszük fel. Ebben az esetben nyilvánvaló, hogy az XML jelölő az egyetlen hasznos adat a dokumentumban. Láthatjuk, hogy sokféle egyszerű módon lehetne kódolni ugyanezt az adatot, de a lényege egyértelmű.
Mind a három dokumentum tiszta példája az adat–orientált dokumentumoknak, mind abban egyeznek, hogy XML jelölőket használnak jól strukturált adatok leírására. A dokumentumokban szereplő adatok segítségével elképzelhetjük, hogy az adatnak egy az egyhez leképezése van az alkalmazásunk jellemzőivel, az XML dokumentumot ezzel az objektumaink szerializált verziójává alakítva. Ez a szerializáció nagyon gyakori az XML-nél, ilyenkor legtöbbször adat-orientált megközelítést használunk. Kiaknázhatjuk a hierarchikus természetét is az XML-nek az összetettebb struktúrák leírásánál.
Erre a folyamatra standard megoldások is beépültek a legtöbb nyelvnél, a Microsoft. NET Framework Common Library olyan funkcionalitásokat tartalmaz, amely bármilyen osztály automatikus XML szerializálására alkalmas, és bármilyen XML deszerializálására az XmlSerializer osztály a System.Xml.Serialization segítségével. A standard Java könyvtárakban ugyan nincs benne, de van egy API, melynek a funkcionalitása nagyon hasonló lesz. Ez az API része a JAVA XML csomagnak, és úgy hívják, hogy JAVA API for XML Binding (JAXB), és XML dokumentumok Java osztállyá történő oda-vissza leképzését kínálja, illetve memóriában tárolt Java objektumok validálását kínálja DTD vagy XML séma ellenében.
Nyilvánvalóan az adat-orientált dokumentumok nem csak szerializált adatstruktúrák megtartására alkalmasak. A Java Bean-ek, de bármilyen más adatszerkezet számára is hasonlóan könnyen történhet az XML-re történő leképzés. Továbbá az XML-t lehet használni bármilyen más adatmegjelenítésére, amelyek nem közvetlenül egy adatstruktúrához köthetőek. Például az Apache Ant építő rendszere is XML fájlt használ a folyamatok leírásához, ebben az esetben egy szoftver létrehozásához. Ezáltal egy jól körülírt folyamatra is lehet úgy gondolni, mint egy jól strukturált adatra.
Összességében elmondhatjuk, hogy az adat-orientált dokumentumok a legjobb választás lehet bármilyen fajta jól strukturált adat ábrázolására. Most pedig haladjunk tovább és figyeljük meg az leíró dokumentumokat, amelyek kevésbé alkalmasak strukturált adatok számára.
Leíró dokumentumok
Az alapvető különbség az leíró dokumentumstruktúrák és adat-orientált dokumentumstruktúrák között az az, hogy a leíró dokumentumstruktúrák felhasználói fogyasztásra lettek tervezve, míg az adat-orientált dokumentumstruktúrák általában alkalmazások számára lettek elkészítve. Az adat-orientált struktúrákkal szemben a leíró dokumentumok általában emberek által olvasható szövegek, amely valamilyen szinten XML jelölővel van kibővítve.
A két alapvető jellemző, amely megkülönböztet egy leíró szöveget egy adat-orientált dokumentumtól a következő:
A tartalmat nem a jelölő határozza meg:
az XML általában nem szerves része a dokumentum által közölt információnak, de valamilyen szinten segít a szöveg kibővítésébe, érthetőségében.
A jelölő adat nagyon strukturálatlan:
míg az adat-orientált dokumentumok egy adathalmazt hivatottak jellemezni, és szigorúan strukturáltak, addig a leíró stílusú dokumentumok szabad folyású szövegként értelmes tartalommal rendelkeznek, hasonlóan mint bármilyen könyv vagy cikkek. Az adatokat ezekben a típusú dokumentumokban lehet strukturálatlannak tekinteni olyan szempontból, hogy a jelölő a dokumentumban nem követ semmilyen szigorú vagy ismétlődő szabályt sem.
Például a címkék száma és a sorrendje egy HTML dokumentumban, a <body> címkén belül végtelenül rugalmas, és dokumentumról dokumentumra változik.
Valószínűleg a legkézenfekvőbb példái a leíró stílusú ( bár nem szigorúan XML) dokumentumoknak a HTML web oldalak, amelyek HTML címkék formájában jelölőket alkalmaznak annak érdekébe, hogy leíróinformációval tegyék színesebbé a weboldal szövegét. Bár ez az információ nagyon fontos és határozottan növeli az olvasó élményét (például ez adja meg a helyét, méretét, színét képeknek és szövegeknek az oldalon), meg kell említenünk, hogy a lényegi információ független a HTML jelölőtől. Ugyanúgy, ahogy a HTML jelölőt használjuk HTML dokumentumokban, hogy megjelenési jellemzőket megadjuk, XML jelölőket használunk a leíró címkéken, hogy olyan dolgokat tudjunk csinálni, mint például a szöveg jelentéssel történő ellátása fogalmak megmagyarázása.
Vegyünk most egy példát, hogyan is lehet a leíró dokumentum struktúrát használni a gyakorlatban. Ha elképzeljük, hogy egy kórház XML-t használna a műtétek alatt eltelt percek bemutatására, akkor az valahogy így nézhetne ki:
<operation>
<preamble>
Az operáció megkezdődött: <time type="begin">09:30</time>,<date>2013-05-30</date>.
A résztvevő orvosok: <surgeon>Dr. Úr Elek</surgeon> és <surgeon>Dr. Mészár Olga</surgeon>, segítő <assistent>Gipsz Jakab</assistent>
</preamble>
<esemény>
Dr Úr egy <tool>szike</tool> segítségével megkezdte a bemetszést <incisionPont>bal térd</incisionPont> vonatkozásában
</esemény>
...
</opeation>
Láthatjuk ebből a példadokumentumból is, hogy a ténylegesen hasznos tartalom a dokumentumban az operáció egyszerű szöveges leírása. Az XML jelölő jelentésbeli pluszinformációt ad a szöveghez, mint például a műtét elkezdésének napja és ideje, kik voltak a műtős orvosok és hasonló megjegyzéseket, de akár ezektől eltekintve is értelmes marad (nem úgy mint a korábbi szakasz adat-orientált dokumentuma a jelölők nélkül).
A leíró dokumentumok széles körben hasznosak lehetnek:
Megjelenítés
az XHTML jó példája annak, hogyan lehet az XML jelölőt alkalmazni leíró stílusú dokumentumokhoz, hogy a megjelenést szabályozzuk (az XHTML egy teljesen XML kompatibilis verziója a HTML-nek)
Indexelés
az alkalmazások hatékony kiemelést tudnak végrehajtani szöveg alapú dokumentumokon XML jelölőt használva a dokumentumban a kulcs elemek azonosítására, aztán indexelik a dokumentumot ezen tartalom segítségével akár relációs adatbázist, akár teljes szöveges indexelő szoftvert használva.
Erre a korábbi (operációkat leíró) XML tökéletes példaként tud szolgálni. Amint ebben a dokumentumnak láthattuk, minden kulcsinformáció ( a dokumentum jelentése) XML címkék által jelölt, amelyek a kategóriájuk által azonosít is. Erre már bátran lehet indexelést végezni.
Annotációk
egy alkalmazás használhat XML-t annotáció hozzáfűzéséhez mér létező dokumentumokban, így téve lehetővé a felhasználók számára annotációk hozzáadását anélkül, hogy a szöveget közvetlenül módosítanák ( hasonlóan ahhoz, amikor egy bíráló tesz megjegyzéseket egy Word dokumentumhoz )
Egy XML dokumentumnak sok jellemzője van, de az a három ami befolyással van a legalapvetőbb szinten egy dokumentum tervezésre az az attribútumok, elemek és karakter adatok hármasa. Ésszerű erre a háromra úgy tekinteni, mint az XML alapvető építő elemeire és a kulcs ahhoz, hogy jó dokumentumokat tudjunk tervezni. (A titok pedig abban rejlik, hogy tudjuk mikor melyik elemet kell használni.)
Az egyik leggyakoribb döntés, amit XML dokumentum tervezők szembesülnek, hogy attribútumokat, vagy elemeket használjanak adatok kódolásához. Nincsen általánosan elfogadott megoldás, és sok esetben stilisztikai üggyé válik a dolog. Azonban, bizonyos körülmények között ( főleg nagyon nagy kiterjedésű dokumentumok esetében) a jó döntés meghozatala kritikus a jó teljesítmény szempontjából a dokumentumok kezelése közben.
Lehetetlen lenne elképzelni minden egyes adat típust, amellyel szembesülhetünk ha XML-ben akarjuk leírni (elkódolni). Éppen ezért lehetetlen szabálylistát felállítani is, amely megszabná mikor kell attribútumot, és mikor kell elemeket használni a kódoláshoz. Átlátva a különbségeket képesek leszünk helyes döntéseket hozni a saját dokumentumainkban - alapul véve az alkalmazásunk követelményeit. Az összehasonlítás nagy része az attribútumok és elemek közötti különbségekre fog koncentrálni, de a karakteradatok szerepét se szabad elfelejteni.
Leíró jellegű dokumentumok „szabálya”
Az adat-orientált dokumentum szerkezetekkel szemben nagyon egyszerű a szabály arra vonatkozólag, hogy mikor használjunk attribútumokat és mikor elemeket: a leíró jellegű szövegnek szöveg tartalomnak kell lennie. A szövegről pedig minden információnak elembe kell kerülni, illetve ezen elemek az attribútumaiba.
Könnyen értelmezhetjük ezt úgy ha egy leíró dokumentum jelölőinek a céljára gondolunk: ez egyszerűen annyi, hogy jelentésbeli adatokat adunk a szöveghez. Bármi, ami jelentésbeli tartalmat ad egy szöveghez elem formátumban kell hogy legyen (mint például a <time> elem a kórházas példánkban), és minden, ami leírja ezt a jelentésbeli értéket annak az elemnek az attribútumának kell lennie. Végezetül, a tartalom, aminek a jelentését az elem módosítja szöveg tartalomként kell hogy megjelenjen az elem kontextusában.
A leíró szöveg egy elem tartalmává válik, az információ a szövegről pedig attribútummá.
Bizonyos esetekben az elemek vagy attribútumok használata az adat kódolására közel sem kritikus. Azonban nagyon jól elkülöníthető viselkedésük van, és bizonyos körülménye között egyiknek vagy másiknak a használata kihatással lehet az alkalmazásunk teljesítményére.
Az elemek feldolgozása több időt és több tárhelyet igényel, mint az attribútumoké ha adott esetben mindkettőt ugyanannak az adatnak a bemutatására használjuk. Ez a különbség nem nagy ha csak egyetlen elemet és egyetlen attribútumot használunk. Azonban különösen nagyméretű dokumentumokkal való munkánál vagy ha a dokumentum méretét a minimum szinten kellene tartanunk (például XML dokumentumokat továbbítunk alacsony sávszélességű csatornán keresztül) ez a különbség határozottan számottevővé válik.
A hely kérdése
Ami a helyet illeti, az elemek mindig több helyet fognak igényelni, mint az attribútumok, mert az elemnek mindig kell XML jelölőt tartalmaznia. Nézzük a a korábban már használt betegeink címe segítégével a következő példát:
<information:address> <information:city>Debrecen</information:city> <information:street>Kis utca 15.</information:street> </information:address>
Igen egyszerű XML kódolás. Ha erre egy C# osztályt kellene létrehozni, akkor egyszerűen sztring tagokkal tennénk és a korábban már említett XML szerializáló osztály pont ezt az eredményt adná. Ez a konkrét kódolás 108 karakterbe került a space-ektől eltekintve. Ugyanezt az adatot viszont tudnánk kódolni elemek és attribútumok keverésével, ami megspórolná a végcímkéket.
<information:address> <information:city v="Debrecen" /> <information:street v="Kis utca 15." /> </information:address>
Ez már így lecsökkent 94 karakterre - bár az olvashatóság rovására ( én tudom, hogy a v a value (értéket) helyettesíti, de bárki más tudná-e?). Ugyan a helyen kívül spórol nekünk némi elemzési időt mivel nem kell foglalkoznunk semmilyen szabad szöveg kontextussal (karakteradatokkal). Bár a használata továbbra sem ajánlott.
Nézzük utoljára azt az esetet ha ugyanazt az adatot kizárólag attribútumok használatával szeretnénk bemutatni:
<information:address city v="Debrecen" street v="Kis utca 15." />
Ez a minimum kódolás, mindössze 69 karakter - figyelmen kívül hagyva a space-t ( ami további 36%-ot spórolt). Ez csak egy egyszerű példája a nagyon nagy dokumentumoknak, amelyek rekordonként több adatot is tartalmaznak. Ez a spórolás kritikus lehet mind a helyben - amit a dokumentum igényel, mind abban az időben amit az extra szöveg olvasására és feldolgozására kell fordítanunk.
Ezt a trendet követve egy kisebb adathalmaz esetén is jelentős eltéréseket tapasztalhatunk. Az attribútum alapú dokumentumok majdnem 40%-al kisebbek, mint az elem alapúak, és körülbelül 35%-al kisebbek, mint a kevert stílusúak. Ebben az esetben a kevert stílusú dokumentumok végül is csak 6%-al lettek kisebbek, mint a csak elemeket tartalmazók.
Erre alapozva tisztán látszik, hogy az olyan helyzeteken ahol fontos a méret, szívesebben akarunk majd attribútumokat használni elemek helyett Tartsuk szem előtt, hogy a dokumentumunknak nem kell szükségszerűen ilyen nagy méretűnek lenni ahhoz, hogy belefussunk ugyanebbe a problémába. Ha az alkalmazásunk több kis dokumentumot használ vagy generál, ugyanúgy bele fogunk akadni.
A hely, amit az elemek igényelnek, a memóriát is emésztheti attól függően milyen feldolgozási módot használunk. Például a DOM-nak minden egyes elemre amit a dokumentumunkban talál új csomópontot kell létrehoznia a fában. Ez azt jelenti, hogy a csomópont összes elemét létre kell hoznia, ami mind memóriát igényel ( és az időről még nem is beszéltünk). Az attribútumok létrehozása és tárolása a DOM fában viszont sokkal kevesebbet igényel, ráadásul néhány DOM implementáció annyira optimalizálja az attribútumokat, hogy egy elem attribútumát addig nem dolgozza fel, amíg nincs rájuk vonatkozó hozzáférés. Ez a feldolgozási idő csökkenéséhez vezet és egyben csökkenti a memóriahasználatot is, miután az attribútum szöveges megjelenése a DOM feldolgozásnál számottevően kevesebb helyet igényel, mint ugyanannak az adatnak az "objektum" formája.
A feldolgozási idő kérdése
Az elemek nem csak tárhelyben, hanem időben is sokkal igényesebbek, mint az attribútumok ( alapul véve azt ahogy a legtöbb alacsony szintű DOM és SAX feldolgozó működik). Az attribútumok jelentősen kisebb költséget termelnek a DOM implementációknál, mivel nem dolgozzák fel őket addig, amíg nem találkoznak velük. Mindemellett megússzuk a szükségtelen többletmunkát, amit az objektumok létrahozása jelentene.
Ezek a dolgok nagyon könnyen összeadódnak, és ahogy majd később láthatjuk, a DOM-ot hamar használhatatlanná tudják tenni mert az elemszám a dokumentum méretének több ezerszeresére tud nőni. Azonban, ha a kedvenc DOM implementációnk különösen jól dokumentált, akkor megnézhetjük a forrását, hogy mennyire optimálisan kezeli az attribútumokat és az elemeket, ellenkező esetben marad a kipróbálása.
A SAX esetében az elemek hátránya egy kicsit kézenfekvőbb. Egy dokumentum minden eleme legalább két metódushívásra fordul: startElement() és endEelement() a feldolgozás során. Sőt, ha a dokumentumunk karaktertartalmat is használ az értékek megadására ( mint a fentebbi példa), akkor legalább egyel több hívása lesz a karakterek miatt. Tehát, ha a dokumentumunknak túl sok eleme van, akkor ez a két vagy a karakterek miatt jóval több metódushívás igencsak csökkenti a feldolgozási kódunk működésének a hatékonyságát. Ellenben ami az attribútumokat illeti, a SAX saját adatstruktúrába csoportosítja őket, találóan az Attributes-be, amit aztán továbbad egy argumentumként a startElement() metódushívásnak. Ezért a létrehozása és a inicializálása az Attributes struktúrának jelentősen lecsökkenti a többletmunka befektetést.
Gyakorlati tapasztalat alapján állíthatjuk, hogy SAX esetén az attribútum stílus feldolgozási idő tekintetében kis méret (kb 10.000 elem esetén) csupán egy kicsivel tűnik hatékonyabbnak, mint a puszta elem stílus, ami egyezik az elvárásainkkal ismerve a SAX-ot. A kevert stílus viszont a legrosszabbul teljesít a háromból, pluszmunkát okozva a hozzáadott elemekkel és attribútumokkal.
Ami a DOM-ot illeti, ahogy várhatjuk, az attribútumok használata óriási spóroláshoz vezethet, hiszen majdnem feleannyi idő alatt feldolgozható. A kevert stílus itt is a legutolsó helyen említendő, mivel valamivel több időt emészt fel, mint a pusztán elemet használó megközelítés.
Nagy elemszám esetén a SAX esetében az arányok az egyes stílusok között nagyjából ugyanazok maradnak, de továbbra is egyértelmű, hogy a kevert stílus teljesít mindig a legrosszabbul - közel kétszer annyi idő szükségeltethet hozzá, mint a pusztán attribútum alapú megközelítés. Ennél egyértelműen rávilágít arra, hogy a kevert stílus nem igazán megfelelő ha a teljesítmény a cél.
A DOM esetében a pusztán attribútum alapú megközelítés közel 45%-nyi időt spórolhat nekünk a pusztán elemeket használó stílussal szemben, és a kevert módszerhez képest is majdnem kétszer olyan gyors lehet. Azt is tény, hogy egy DOM megoldás több, mint háromszor annyi időt vesz el tőlünk, mint a megegyező SAX megoldás. Ez jól illusztrálja azt a tényt, hogy a DOM nem kezeli jól azokat a dokumentumokat, amelyeknek kimagaslóan sok az elem szám.
Az attribútumok kimondottan limitáltak annak tekintetében, hogy milyen adatot tudnak megjeleníteni. Egy attribútum csak karakteres értéket tud tartalmazni. Egyáltalán nem alkalmasak semmilyen strukturált adat befogadására, egyértelműen rövid sztringekre hivatottak. Az elemek ezzel szemben kimondottan alkalmasak strukturált adatok befogadására, mivel tartalmazhatnak beágyazott elemeket és karakter adatokat is.
Mindazonáltal tárolhatunk strukturált adatot egy attribútumban, de így magunk kell minden kódot megírnunk, hogy azt a sztringet értelmezni tudjuk. Bizonyos esetekben ez elfogadható lehet, például életszerű egy dátumot attribútumként tárolni. Az elemző kódunk valószínűleg kielemzi a sztringet ami a dátumot tartalmazza. Ez valójában egy elég okos megoldás, mert élvezhetjük az attribútum előnyeit szemben az elemekével, továbbá az idő, hogy ezt kielemezzük minimális, tehát még XML feldolgozási időt is spórolunk.
( Megjegyzendő, hogy ez a megoldás dátumoknál nagyon jól működik, mert azoknak elég általános formátumuk van amikor sztringként szerepelnek, ezért nem igényelnek különösebb előismeretet az elemzés szempontjából. Azonban ennek a technikának a túlzásba vitt használata tönkreteszi az XML ábrázolást, így inkább óvatosan használjuk)
Általában véve nem tanácsos túlságosan kreatívnak lenni strukturált adat egyetlen sztringgé való kódolásakor. Ez nem a legjobb használata az XML-nek, és nem is az ajánlott gyakorlat, ellenben tisztán mutatja a flexibilitás hiányát, amit az attribútumok képviselnek. Ha az attribútumokat ilyen módon használjuk, akkor valószínűleg nem aknázzuk ki az XML-ben rejlő lehetőségeket. Az attribútumok nagyon jól teljesítenek abban, hogy tároljanak relatíve rövid és strukturálatlan sztringeket - és ez az amire használni kellene őket az esetek többségében. Ha mégis olyan helyzetben találjuk magunkat, hogy relatíve komplikált szerkezetű szöveget kell tárolni a dokumentumunkban, akkor érdemes karakteradatként tárolni, aminek nagyon egyszerű oka van: a teljesítmény.
Azon kívül, hogy a nagyon hosszú sztringek egy attribútum értékében stilisztikailag nem kívánatosak, problémát okozhatnak a teljesítmény terén is. Mivel az attribútum értékek csak sztring példányok, a feldolgozónak az egész értéket egyszerre kell a memóriájában tartania. Nagyon hosszú sztringek esetében a memória is problémát jelenthet kimondottan nagy hossznál. A SAX esetében a nagyon nagy karakteradatok kisebb probléma, mert számtalan kisebbe tördeli, amelyeket aztán egyenként dolgoz fel a ContentHandler characters() metódusa, így az egész sztringet nem kell a memóriában tartani egyszerre.
Ez leginkább stilisztikai dolog, de van néhány irányvonal ami segít a választásban. Megfontolandó a karakteres adat használata amikor:
az adat nagyon hosszú
Az attribútumok nem alkalmasak nagyon hosszú értékek tárolására, mivel az egész értéket egyszerre kellene a memóriában tartani.
Nagy számú levédett (escapelt) XML karakter van
Ha karakteradatokkal dolgozunk, használhatjuk a CDATA szekciót annak érdekében, hogy elkerüljük a sztring XML levédését. Például, attribútumot használva egy logikai kifejezésre valami hasonlóval találhatjuk szembe magunkat:
"a < b & b > c "
Azonban, ha karakteradatot használtunk volna, ugyanazt a sztringet sokkal olvashatóbb formában is kódolhattuk volna:
<![CDATA[ a < b && b > c ]]>
Az adat rövid, de a teljesítmény fontos és SAX-ot használunk
Ahogy láthattuk a kevert stílusú dokumentumoknál a karakteradatok lényegesen kevesebb időt emésztenek fel feldolgozás alatt, mint az attribútumok a SAX esetében.
Meggondolandó az attribútumok használata amikor:
Az adat rövid és strukturálatlan
Ez az, amire az attribútumokat kitalálták, de vigyázzunk, mert a teljesítmény sérülhet a karakteradatokkal szemben különösen nagy dokumentumok esetében ( >100.000 elem) ha SAX-ot használunk.
SAX-ot használva a feldolgozó kódot egyszerűnek akarjuk látni
Sokkal egyszerűbb attribútum adatokat feldolgozni, mint karakter adatokat. Az attribútumok elérhetőek amikor egy elem kontextusát kezdjük parszolni. Karakteradatok feldolgozása sem túl komplikált, de néhány extra lépést és extra logikát megkíván ami hiba forrás lehet, különösen a SAX-ot kezdőként használóknál.
Számos esetben van az adatoknak olyan jellemzője ( vagy jellemzők egy halmaza) amely arra szolgál, hogy egyértelműen meg lehessen különböztetni a többi hasonló típusú adattól. Például egy ISBN szám, vagy egy szerző és cím kombinációja felhasználható könyvobjektumok egyértelmű beazonosítására.
Az attribútumok használata az elemekkel szemben leegyszerűsítheti a feldolgozás folyamatát bizonyos körülmények esetén. Például ha nincsen alapértelmezett konstruktora annak az osztálynak amit deszerializálunk, akkor a kulcsadatok attribútumként való használata leegyszerűsíti az objektum létrehozását. Szimplán azért, mert a létrehozáshoz szükséges adatok már az elem nyitó címkéjének elérésekor rendelkezésre állnak (egy SAX feldolgozóra gondolva). A kód is tiszta lesz, mert nem fognak a metóduson belül tobzódni a különböző típusú elemek, így mindig tudjuk, hogy hol járunk és mit dolgozunk épp fel.
Ezzel szemben ha elemként tároljuk el a kulcsadatokat, akkor a feldolgozó kód nehezen követhetővé válik. Bonyolult, mert folyamatosan vizsgálni kell, hogy épp milyen típusú elembe futottunk és hogy már feldolgoztuk-e a továbblépéshez szükséges adatokat, ami összetettebb és átláthatatlanabb kódot eredményezhet.
Hasonló a helyzet ha egy dokumentum tartalmát validáljuk. Előfordul, hogy csak egy gyors ellenőrzést szeretnénk a dokumentumon végrehajtani mielőtt egy mélyebben szántó, kiterjedtebb dokumentum feldolgozást tennénk. Ez különösen hasznos rétegelt, elosztott rendszereknél: egy kevés validálást végrehajtva az elején szükségtelen forgalmat kerülhetünk el az alacsonyabb rétegeknél vagy magán a hálózaton ( például egy megrendelőrendszer ellenőrzi egy kredit kártya formátumát és számát mielőtt a megrendelést továbbítja a végrehajtó felé).
Ezekben a helyzetekben óriási segítséget jelent, ha az azonosító vagy kulcsinformáció attribútumként és nem elemként szerepel. A feldolgozó kód nagyban leegyszerűsödik, ahogy már tárgyaltuk és a teljesítmény is sokkal jobb lehet, mivel teljesen mellőzhetjük a tartalom túlnyomó részét a dokumentumban és hamar a feldolgozási folyamat végére érhetünk.
Végső soron, az attribútumok elemekkel szembeni preferálása nagyrészt stilisztikai ügy, mivel többnyire ugyanazt az eredményt érhetjük el bármelyik megközelítést is használjuk. Azonban vannak olyan helyzetek, amikor az attribútumoknak egyértelmű előnyük van adatok azonosításában. Röviden, amikor a dokumentumok szerkezetét határozzuk meg, győződjünk meg arról melyik kategóriába tartozik.
Az elemekkel ellentétben, az attribútumoknál nincsen kötött sorrend, nem számít, hogyan adjuk meg az attribútumokat egy sémában, vagy DTD-ben, nincsen olyan megkötés, hogy az attribútumoknak milyen sorrendet kellene követniük. Mivel az XML nem követel meg semmilyen attribútum sorrendiséget, ennek eredményeként az olyan helyzetekben, ahol az értékek sorrendje fontos, az elemek használta jobb választás, mint az attribútumoké, mert csak így tudjuk kikényszeríteni a számunkra fontos sorrendet.
Az a mód ahogyan XML-ben modellezzük az adatainkat gyakorlatilag hatással lesz annak minden aspektusára ahogy az emberek és alkalmazások kapcsolatba kerülnek ezekkel a dokumentumokkal. Ezért kritikus, hogy az adat amit ábrázolunk, az interakciót hatékonnyá és problémamentessé tegye. Ezidáig egy nagyon alacsony szinten érintettük a modellezést, azt vitatva, hogy mely XML primitívek (elemek és attribútumok) alkalmasabbak a különböző helyzetekben. A fennmaradó részében picit magasabb szintű irányvonalakat fogunk megnézni.
Kerüljük a speciális platformra vagy feldolgozó implementációra való tervezést
Az XML egyik legnagyobb vonzereje abban rejlik, hogy hordozható és platform-független. Nagyszerű eszközzé teszi arra, hogy megosszunk adatot egy heterogén környezetben. Amikor dokumentumokat arra használják, hogy megosszanak adatokat vagy egy külső alkalmazással kommunikáljanak, a dokumentum tervezése elképesztően fontossá válik.
Tervezőként figyelembe kell vennünk számos tényezőt. Csak egyet említve: az adatok szerkezetének megváltoztatásának az ára. Miután megjelent és írott kódok készültek erre a szerkezetre épülve a változtatás majdhogynem tiltott. Sőt, miután publikáltunk egy dokumentum szerkezetet a külvilág számára, gyakorlatilag minden uralmat elvesztünk fölötte. Érdemes arra is gondolni, hogy a szerkezetünknek megfelelő dokumentumok hogyan lesznek feldolgozva.
Soha nem jó ötlet egy dokumentumszerkezetet valamilyen feldolgozó verziójához készíteni. Nem arra gondolok, hogy olyan dokumentumot tervezzünk, ami egy adott feldolgozó technológiához alkalmazkodik (mint a DOM, SAX, vagy pull-feldolgozók), inkább arra célzok, hogy valamilyen verzióra tervezünk - mintha a JAVA kódunkat egy specifikus VM-hez igazítanánk. A feldolgozók fejlődnek és egyre jobbak lesznek az idővel, tehát nincsen sok értelme egy bizonyos implementációhoz optimalizálnunk.
Ennek eredményeként a legjobb amit dokumentumtervezőként tehetünk, hogy úgy szabjuk meg a dokumentumunkat, hogy annak az igényeit elégítse ki amit szolgálni fog. A dokumentum struktúrája csak egy szerződés, semmi több, nem interfész és nem implementáció. Ezért kiemelkedően fontos, hogy értsük azoknak a dokumentumoknak a használatát amelyek ezt a struktúrát követik.
Adatbázis szemléletet követve vegyük például azt az esetet amikor mondjuk tömeges illetve csak sor-orientált adatbázis interfészt használunk. Ha az API-nk sorok százait, vagy ezreit fogja befolyásolni az adatbázisban, akkor valószínűleg úgy terveznénk, hogy tömböket vagy kollekciókat használnánk paraméterként, miután egyetlen adatbázis lekérdezés ami több ezer sort érint az jelentősen gyorsabb, mint rengeteg lekérdezés ami csak egyetlenegy soron fut le. Nem szükséges ismerünk az Oracle-t vagy az SQL Server-t különösebben, hogy ilyen helyzetben jó döntést tudjunk hozni.
Hasonlóan, amikor dokumentum szerkezetet tervezünk, sokkal inkább érdemes a technológiák széles körű felhasználásra fókuszálnunk, mint egy bizonyos implementáció speciális jellegzetességei miatt aggódnunk. Sokkal fontosabb megérteni az elemek és attribútumok általános teljesítményjellemzői közötti különbséget, mint azt tudni, hogy egy bizonyos feldolgozóimplementáció optimalizált-e nagyszámú attribútumok feldolgozására vagy sem. A fenti példát folytatva ha olyan dokumentum szerkezetet tervezünk, amiről tudjuk, hogy több ezer bejegyzést fog tartalmazni, fontos tudnunk hogy az elemek alkalmazása jelentős teljesítmény romlást okozhat akár lemezhasználat szempontjából, akár annak az időnek a szempontjából ami alatt a dokumentum feldolgozható lesz.
Ha dokumentumaink nem kizárólag csak a mi alkalmazásunknak készül, mindenképp győződjünk meg arról, hogy úgy tervezzünk a dokumentum szerkezetét, hogy véletlenül se függjön semmilyen platformspecifikus, vagy feldolgozó implementáció specifikus jellemzőtől.
Az alapul szolgáló adatmodell többnyire nem a legjobb választás az XML-hez
Az XML-t gyakran használják olyan helyzetekben, ahol nem ez az állandó megjelenítési formája a leírt adatnak. Gondoljunk például az XML alapú RPC-re, ami kötődik a webszolgáltatásokhoz. Az XML RPC esetében a távoli eljárás paraméterei, ugyanúgy, mint a visszaadott értéke (már ha van ilyen) XML-ben vannak leírva egy SOAP-nak megfelelő dokumentumban. Attól, hogy XML-t használtunk a távoli végrehajtásra még egyértelműen látszik, hogy ez nem az elsődleges ábrázolása az adatoknak - ez csak egy másodlagos reprezentáció, amely csak átalakításra szolgál.
Az ilyen helyzetekben, ahol az XML csak köztes kódolását végzi az adatoknak, gyakran jó ötlet újragondolni az adatunk szerkezetét, ahelyett hogy egyszerűen csak újrahasználnánk a már meglévő szerkezetet, mint XML-alapú struktúrát. Gyakran, az alap adatmodell nem a legoptimálisabb az XML számára.
Megint köthetünk az adatbázisok világához, a legtöbb perzisztens tároló mechanizmus, mint például a relációs adatbáziskezelők, az egyszerű fájlok, az objektum adatbázisok vagy bármi hasonló nem az XML figyelembevételével és annak szerkezetét szem előtt volt tervezve. Mindegyik speciális célok miatt jött létre, és ennek fényében vannak erősségeik és gyengeségeik.
Az egyik leggyakoribb használata az XML-nek az olyan adatok leírása amelyeknek az állandó reprezentációja relációs adat valamilyen RDBMS-ben. A relációs adatbázisoknak egyszerű szerkezetük van, melyek különálló táblákat tartalmaznak, amiknek az egyetlen kapcsolódási pontjuk egymással logikai. Ezeket a kapcsolatok a külső kulcsok definiálják. Relációs adatbázisokat használni hierarchikus adatokra általában azt jelenti, hogy van egy adattábla, amely a „szülőt” jelöli a hierarchikus kapcsolatban, és külön egy tábla (vagy táblák) a „gyerekeket” reprezentálva a kapcsolatrendszerben.
Ha ezt a táblastruktúrát kellene egy XML dokumentumban ábrázolnunk, az eredmény egy igen használhatatlan dokumentum szerkezet lenne, amely szükségtelen komplikációkat és plusz munkát adna a feldolgozási folyamathoz, mert nem használja az XML egyik legnagyszerűbb jellemzőjét: annak a tudását, hogy hierarchikus adatokat ábrázoljon. Gyönyörűen el lehet érni olyan lapos (2D-s) dokumentum szerkezeteket, amelyek köszönő viszonyban sincsenek az XML valódi arcával, mint a következő példa.
<?xml version="1.0"?> <planet name="earth"> <record region="Africa" country="Mauritius" language="Bhojpuri" year="1983" females="99467" males="97609"></record> <record region="Africa" country="Mauritius" language="French" year="1983" females="19330" males="16888"></record> <record region="Europe" country="Finland" language="Czech" year="1985" females="42" males="36"></record> <record region="Europe" country="Finland" language="Estonian" year="1985" females="330" males="102"></record> <record region="Far East" country="Nepal" language="Limbu" year="1981" females="65318" males="63916"></record> <record region="Far East" country="Nepal" language="Magar" year="1981" females="107247" males="105434"></record> <record region="Middle East" country="Israel" language="Russian" year="1983" females="56565" males="44500"></record> <record region="Middle East" country="Israel" language="Yiddish" year="1983" females="101445" males="87775"></record> <record region="North America" country="Canada" language="English" year="1981" females="7521960" males="7396495"></record> <record region="North America" country="Canada" language="French" year="1981" females="3178190" males="3070905"></record> <record region="South America" country="Paraguay" language="Castellano" year="1982" females="91431" males="75010"></record> </planet>
Ha vennünk kéne ezt a szerkezetet és közvetlenül XML-be áttenni, leginkább egy olyan dokumentum szerkezetet kapnánk, ami így festene:
<?xml version="1.0"?> <planet name="earth"> <region name='Africa"> <countries> <country name="Mauritius"> <languages> <language name="Bhojpuri" year="1983" females="99467" males="97609" /> <language name="French" year="1983" females="19330" males="16888" /> </languages> </country> </countries> </region> <region name="Europe"> <countries> <country name="Finland"> <languages> <language name="Czech" year="1985" females="42" males="36" /> <language name="Estonian" year="1985" females="330" males="102" /> </languages> </country> </countries> </region> ... </planet>
Egy sokkal természetesebb XML szerkezete az ilyen típusú dokumentumoknak, itt már fel lehet fedezni az eredeti adatbázisban rejlő kapcsolatokat is. Ezt a dokumentumot sokkal könnyebb olvasni, mint az előzőt miután kihasználja az XML saját belső hierarchikus szerkezetét, hogy az adatokat egy sokkal természetesebb módon mutassa be. A dokumentum ilyen jellegű strukturálása a feldolgozó kódot is egyszerűbbé és hatékonyabbá teszi a dokumentumok számára.
A legfontosabb dolog, amit szem előtt kell tartanunk amikor a dokumentumunk szerkezetét tervezzük, hogy arra az absztrakt modellre épüljön, amely leginkább leírja azt, amit kódolni szeretnénk. Véletlenül se a modell valamilyen más technológiában (Java, C++, ...) készült implementációjára. Természetesen előfordulhatnak olyan helyzetek ahol a modell szoftver implementációja és az XML implementáció nagyon hasonlóak, de alapvetően nem ez szokott igaz lenni. Ez a fajta analízis általában segít egy XML-barátabb adatmodell kialakításában, ami robusztusabb dokumentumokat eredményez egyszerűbb feldolgozó kóddal és jobb teljesítménnyel a feldolgozás során.
Kerüljük a dokumentumok túltelítését
Az XML használatának egyik mellékhatása az a sok pluszmunka ami kézen fogva jár a kódolással. Őszintén megvallva az XML nem a leghatékonyabb leíró mechanizmus. A dokumentum minden egyes adata mindig együtt járó valamilyen jelölő megjelenésével. Általában véve érdemes a dokumentumméretét olyan kicsin tartani, amennyire csak lehetséges számos ok miatt:
bár a lemezen a hely olcsó, mégsem ajánlatos pazarolni,
minden egyes bitje a dokumentumnak át fog folyni egy XML feldolgozón, tehát minél hosszabb a dokumentum, annál tovább tart ez a folyamat,
ha a dokumentumot kommunikációs eszközként fogják használni, mint például egy SOAP dokumentumot egy XML-alapú webszolgáltatáshoz, az egészet ki kell majd küldeni a hálózatra.
Ugyan a hosszú elem és attribútum nevek kiemelt szerepet játszhatnak a dokumentum méretében, de mégsem ez az a tipikus hely ahonnan elveszünk, amikor próbáljuk a dokumentumunk méretét ésszerű keretek közé szorítani. Érdemes megbizonyosodni arról, hogy a dokumentumunk könnyen olvasható maradt. (és azt se szabad elfelejteni, hogy ezek lesznek azok a pontok, amelyek egy tömörítés esetén a legkisebb méretre zsugorodnak)
Gyakran célravezető, ha a ténylegesen a dokumentumba kerülő adatokat kielemezzük annak érdekében, hogy elkerüljük a fölösleges bitek szaporítását. Gyakori az a tendencia XML kódolásnál, hogy csak úgy beküldjük kódolásra ez egészet, anélkül, hogy átnéznénk. Gondolhatunk itt például a származtatott adatok problémakörére. Hasonló a helyzet replikáció esetén is. Felesleges a teljes adatbázist utaztatni, elegendő a változásokat. Az ideiglenes adatokat se szükséges többnyire kódolni. Java esetén amit transient jelzővel láttunk el nem kerül automatikusan szerializációra. Az olyan mezők, amelyek ideiglenes állapotot tárolnak, mint a cache, vagy közbenső állapotok egy hosszan futó kalkuláció alatt általában ilyen tranziens változók.
Természetesen túlságosan megnyirbálni se célszerű dokumentumunkat, ez mindig egy egyensúly megtartása a jelenlegi teljesítmény és a jövőbeli rugalmasság között. Meg kell hoznunk a saját döntéseinket, amelyek a saját alkalmazásaink követelményeit tartják szem előtt. Egy kicsit több odafigyeléssel, hogy mely adatok is vannak valójában a dokumentumunkban, és ezt összehasonlítva azzal, hogy mire is van szükség, kisebbre foghatjuk a dokumentumunk méretét, így könnyebben feldolgozhatóvá és kezelhetőbbé válik.
Az utolsó általános szabály pedig, hogy kerüljük a redundanciát amikor a dokumentum szerkezetét építjük. Ez át is vezet a következő problémakörhöz.
Kerüljük a hivatkozásokkal túlterhelt dokumentum struktúrák használatát
Az egyik legfájdalmasabb pont egy XML feldolgozó kód írásánál, ha a feldolgozandó dokumentum szerkezet nagyon sűrűn használ referenciákat, amelyek ehhez hasonlóan néznek ki:
<document> <anElement name="szulo" /> <anElement name="gyerek" parent="szulo" /> </document>
Ez a példa nagyon egyszerű módon szemlélteti a hivatkozások használatát. Azonban ne felejtsük el, hogy a hivatkozások pusztán szöveges alapúak, és csak nagyon kevés nyelvi elem támogatja a használatukat, a feloldásuk és kezelésük általában az alkalmazás kód feladata.
Természetesen a hivatkozások bizonyos körülmények között nagyon hasznosak lehetnek az XML-ben. Például az Ant build rendszer XML-t használ, hogy a folyamatokat leírja, és egy Ant build fájlban hivatkozásokat használunk, hogy a cél függőségeit megadjuk. Itt egy gyors példa:
<project name="MyProject" default="dist" basedir=".">
<description>
simple example build file
</description>
<!-- set global properties for this build -->
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>
<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>
<target name="compile" depends="init" description="compile the source " >
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}"/>
</target>
<target name="dist" depends="compile"
description="generate the distribution" >
<!-- Create the distribution directory -->
<mkdir dir="${dist}/lib"/>
<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
<jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
</target>
<target name="clean" description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
</project>A hivatkozásokkal terhelt dokumentumok feldolgozási folyamata elég komplikált lehet, és attól
függően, hogy milyen méretű a dokumentumunk, illetve milyen a szerkezete, a hivatkozásokkal való bíbelődés tönkreteheti a feldolgozó kódunk teljesítményét, és nagyon nehezen követhetővé mások számára. A gond az a hivatkozásokkal terhelt dokumentumok használatánál, hogy a hivatkozások feloldását nekünk magunknak kell csinálnunk. ( Ez legalábbis igaz DOM és SAX esetében. XSLT, ami magasabb szintű ezeknél robusztusabb mechanizmusai vannak a hivatkozások feloldásra).
Mindazonáltal a hivatkozásfeloldás nem egy elviselhetetlenül bonyolult technikai probléma, általában nagyon is egyszerű a kód megírása, főleg, ha a kapcsolat egy-az-egyhez, vagy egy-a-sokhoz. A probléma inkább ott jelentkezik, hogy a feloldáshoz jelentős méretű „állapotot” kell a memóriában tartanunk a teljes folyamat alatt. Ez nem nagy ügy, ha a dokumentum kicsi, de ahogy
a dokumentum mérete növekszik, úgy növekszik az állapot mérete is és ez egy bizonyos pont után
probléma lehet. (Gondoljunk arra hogyha DOM-ot használunk a dokumentum feldolgozására, akkor
ez különösen problematikus pont, hiszen a DOM egyébként is megköveteli, hogy az egész dokumentum a memóriában legyen.
Nézzünk egy példát. Mondjuk, hogy egy olyan dokumentumot dolgozunk fel, ami nagyon sok hivatkozást használ egy egyszerű, nem rekurzív szülő-gyermek kapcsolatra. A dokumentumban a szülők fognak elöl szerepelni, a gyerekek pedig utánuk.
<document> <parent name="szulo1" /> <parent name="szulo2" /> ... <gyerek name="gyerek1_1" parent="szulo1" /> <gyerek name="gyerek2_1" parent="szulo1" /> ... <gyerek name="gyerek1_2" parent="szulo2" /> <gyerek name="gyerek2_2" parent="szulo2" /> ... </document>
Ahhoz, hogy sikeresen feldolgozzuk ezt a dokumentumot, kell, hogy legyen valamennyi információnk a szülőkről a gyerek elemek feldolgozásához. Például ellenőriznünk kell, hogy minden egyes gyereknek van referenciája egy érvényes szülőhöz ( ezt hivatkozási integritásnak nevezzük). Az is lehet, hogy a szülő jellemzőiről is információval kell rendelkeznünk ahhoz, hogy a gyereket feldolgozhassuk.
Ha a szülők száma relatíve kevés, a szülő adatok által a memóriában foglalt extra hely valószínűleg nem fogja a rendszerünk összeomlását okozni. A SAX parszoló kódját viszont bonyolultabbá teszi, mivel egy kódot kell írnunk, ami az adatokat kezeli. Azonban már viszonylag nagyobb számú szülő jelenléte jelentősen befolyásolhatja a feldolgozási kódunk teljesítményét, mert a memória használat egyenesen arányosan növekszik a szülő elemek számával a dokumentumban. Sőt, bármilyen kollekciónak, amit a parszoló kódban használunk a kezelésükhöz megfelelő méretűnek kell lennie, vagy állandóan növelni kell őket (vektorok, listatömbök), ami szintén memóriát és rengeteg feldolgozási időt felemészt.
A hivatkozások problémája súlyosbodhat, ha a hivatkozó elemek hamarabb jönnek, mint a hivatkozottak. Például, ha újraírnánk a dokumentumunkat oly módon, hogy a gyerekek hamarabb jönnének, mint a szülők, a memóriában tartandó adatmennyiség sokkal nagyobb lenne. Valószínűleg legalább annyi gyerek lesz, mint szülő, ha nem több. Ahhoz, hogy ebben az esetben sikeresen dolgozzuk fel a dokumentumot, az összes gyerek adatát a memóriában kellene tartanunk, amíg meg nem találjuk és fel nem dolgozzuk a hozzájuk tartozó szülőket. Amikor megtalálnánk egy szülőt, az összes hozzá tartozó gyereket szeretnénk feldolgozni, ami tovább bonyolítja a kódot a feldolgozási folyamat elvégzéséhez.
A legtöbb ilyen hivatkozási problémát elkerülhetjük, ha a dokumentumunk egy-az-egyhez, vagy egy-a-sokhoz kapcsolatot alkalmaz, kihasználva az XML hierarchikus természetét. A hierarchikus adatok feldolgozása a hivatkozásokkal szemben sokkal kedvezőbb kód és memória használatot eredményezhet.
A korábbi példát folytatva, ha újraírnánk a szülő-gyermek dokumentumunkat hierarchikus szerkezetet használva, nem csak egyszerűbbé, hanem lényegesen tisztábbá és olvashatóbbá tenné:
<document>
<parent name="szulo1">
<gyerek name="gyerek1_1" />
<gyerek name="gyerek2_1" />
</parent>
<parent name="szulo2">
<gyerek name="gyerek1_2" />
<gyerek name="gyerek2_2" />
</parent>
...
</document>Ha a dokumentum hierarchikus struktúrájú, egy adott csomópont szülőjét a dokumentum szövege tartalmazza. Ezért ahhoz, hogy a gyerekeket feldolgozzuk, az egyetlen szülő, amit szem előtt kell tartanunk az adott szövegben található. Amikor a szülő kikerül a szövegkörnyezetből, garantált, hogy nem lesz ehhez a szülőhöz tartozó több gyermek, így nem szükséges ennek a szülőnek az adatait tovább őrizgetnünk. Ennek a fajta szerkezetnek az is nagy előnye, hogy az ember által sokkal olvashatóbb.
Az Ant esetében viszont ez nem használható ki, mert olyan adatokat modellez, amilyenek sok-a-sokhoz kapcsolatban állnak és egy adott cél bármilyen számú másik céltól függhet, és bármely cél lehet függősége bármilyen másik célnak. Az ilyen helyzetekben természetesen nem érdemes az adatokat hierarchikusan kódolni, mivel nincsen általános minta arra, melyik cél milyen tartalmazási viszonyban áll a másikkal.
Amikor dokumentumot tervezünk törekedjünk arra, hogy használjunk hierarchikus szerkezetet hivatkozások helyett. Ha olyan adatot kell modelleznünk, ami megkívánja a hivatkozásokat, próbáljuk meg a dokumentumot a feldolgozókóddal a fejünkben megtervezni, így legalább a memóriaszükséglet tervezhető lesz a feldolgozás ideje alatt.