Az esetek többségében XML fájlunk két (sokszor el nem különülő) részből áll: a kérésre adott adatokból, valamint kiegészítő információkból. Hogy ezekből melyiket hasznosítjuk, az az igényeinktől függ; lehet, hogy csak a fő adatokra van szükségünk (például össze szeretnénk szedni hasonló technológiával készült termékek paramétereit, és azokat egy gyűjtőoldalon megjeleníteni), de lehet, hogy mindenre (ha egy konkrét weboldalt szeretnénk megnézni, ebben az esetben a kiegészítő információkból épül fel a HTML).
Lássuk akkor egy példán keresztül, hogyan is működik az XML alapú web! Egy nagyon egyszerű blogbejegyzés-gyűjtőoldalt készítettem el, amihez mellékelem a két letölthető példafájlt, és a blog.xml-t megnyitva megtekinthető az eredmény. Ez a leginkább kezdők számára készült a leírás szájbarágós stílusú, ezért akik már ismerik az XML + XSL működését, nyugodtan kihagyhatják.
(Mivel a blog.hu nem enged meg fájlokat feltölteni .xsl kiterjesztéssel, ezért hozzábiggyesztettem egy .xml-t)
A blog.xml második sorában lévő <?xml-stylesheet type="text/xsl" href="blog.xsl.xml" ?> utasítja a böngészőt, hogy töltse be a megadott stíluslapot, és annak segítségével jelenítse meg. Azért nevezik stíluslapnak, mert elveiben hasonlóan működik a CSS stíluslapokhoz, azaz szabályokat definiálhatunk benne, hogy az adott adatblokkot mivé alakítsa át. A generált adatok formátuma lehet XML, HTML és szöveges tartalom.
Egy XML fájlban egy gyökér elem, azaz root node lehet, minden tartalomnak azon belül kell lennie; esetünkben ezt <blog>-nak neveztem el önkényesen. A kiegészítő információknak létrehoztam egy saját elemet, és a <tartalom> blokkban helyeztem el a képzeletbeli blog bejegyzéseit. Mint látható, minden bejegyzésnek egyszerű szöveges tulajdonságai vannak, valamint a <szoveg> elemben HTML kódot találhatunk, amit értelemszerűen egy az egyben fogunk megjeleníteni.
A blog.xsl.xml-ben találjuk a megjelenítéshez szükséges beállításokat és stílusokat. A kimeneti adatformátunk HTML (mint látható, megadhatjuk a doctype-ot), amihez UTF-8 karakterkódolást használunk.
<xsl:output method="html" version="1.0" encoding="utf-8" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN" doctype-system="http://www.w3.org/TR/html4/loose.dtd" />
A 7. sorban található <xsl:key ... /> sorral most nem foglalkozom, ami számunkra fontos, az az első stílusdefiníció:
<xsl:template match="blog">
<html>
<head>
<xsl:call-template name="html_fejlec" />
</head>
<body>
<div id="fejlec">
<h1><xsl:value-of select="//kiegeszito_informaciok/cim" /></h1>
</div>
<div id="tartalom">
<xsl:apply-templates select="tartalom" />
</div>
<div id="lablec">
copyright (c) Hidvégi Gábor
</div>
</body>
</html>
</xsl:template>
A bemenő XML értelmezése úgy történik, hogy a feldolgozó szoftver végigiterál az összes XML elemen, megnézi, hogy tartozik-e hozzá stílusdefiníció, ha igen, akkor azt alkalmazza. Esetünkben az <xsl:template match="blog"> azt jelenti, hogy minden <blog> elemet lecserél a definícióban található blokkra. Ez a példában egyszer fordul elő, mivel csak a gyökér elemet neveztem el így, de ha a tartalmi szekcióban is így neveznék el egy elemet, akkor elég érdekes lenne a végeredmény.
A következő sor a <xsl:call-template name="html_fejlec" />, ahol egy névvel ellátott definíció eredményét illesztjük bele a generált HTML kódunkba, nevezetesen a <title> és <meta> tag-eket. Az oldal címe a bemenő XML <kiegeszito_informaciok> blokkja cim elemének tartalma, és a későbbiekben ugyanezt az adatot használjuk a <div id="fejlec">-ben lévő <h1> értékének beállításához is.
Hadd hívjam fel a figyelmet a "html_fejlec" nevű stílusdefinícióban található programrészletre, ami a <meta name="keywords"> tartalmának generálásáért felelős!
<xsl:attribute name="content">
<xsl:for-each select="//cimke[generate-id() = generate-id(key('cimkek', .)[1])]">
<xsl:value-of select="." />
<xsl:if test="position() != last()">, </xsl:if>
</xsl:for-each>
</xsl:attribute>
Működését tekintve ez összegyűjti a bemenő XML-ben található összes egyedi <cimke> elemet, és összefűzi őket egy karakterláncba, vesszővel elválasztva, azaz az eredmény körülbelül így fog kinézni: <meta name="keywords" content="internet, http, szemantikus web">.
Ami ebben különleges, az az elv: nem a szerveroldalon dől el, hogy bizonyos adatokat milyen formában írunk ki, hanem a kliensoldalon, így nem kell a háttérrendszer programozóinak azzal foglalkozniuk, hogy számunkra ugyanazokat az adatokat több módon legenerálják. Már korábban többször említettem, hogy szemléletváltásra van szükség a szemantikus web bevezetéséhez, ez erre egy kiváló példa.
Visszatérve a példára, a következő érdekes sor:
<xsl:apply-templates select="tartalom" />
Ez azt csinálja, hogy a bemenő adatokban megkeresi a <tartalom> elemet, a benne lévő elemeken végigiterál, és ha tartozik hozzájuk stílusdefiníció, azokat feldolgozza és beilleszti erre a helyre. Ha megnézzük a blog.xml-t, a <tartalom>-on belül a <bejegyzesek>-et találjuk, azon belül pedig <bejegyzes> elemeket.
<xsl:template match="bejegyzesek">
<div id="bejegyzesek">
<xsl:for-each select="bejegyzes">
<xsl:call-template name="bejegyzes" />
</xsl:for-each>
</div>
</xsl:template>
A fenti definíció segítségével dolgozzuk fel a <bejegyzesek>-et, amiben egy ciklus segítségével végigiterálunk az összes <bejegyzes>-en, és meghívjuk a hozzá tartozó stílust.
A könnyebb érthetőség végett leírom, hogyan működik pontosan a fenti definíció. Az <xsl:template match="bejegyzesek"> hatására a feldolgozó a bemenő XML fájlban megkeresi az összes <bejegyzesek> elemet (esetünkben egyet), és annak tartalmát adja át a stílusnak, ami a következő XML töredék:
<bejegyzes>
...
</bejegyzes>
<bejegyzes>
...
</bejegyzes>
Első lépésként "kirajzolja" ezt a sort:
<div id="bejegyzesek">
Ez után következik az iteráció:
<xsl:for-each select="bejegyzes">
Ez "fogja" az első <bejegyzes> tartalmát, és átadja a <xsl:call-template name="bejegyzes" /> utasításban megjelölt "bejegyzes" nevű stílusdefiníciónak, amelyik tehát a következő XML töredéket kapja meg:
<cim>A HTTP protokollról</cim>
<url>a_http_protokollrol</url>
<szerzo>Hidvégi Gábor</szerzo>
...
Amikor ebben a stílusban a vezérlés a <h2><xsl:value-of select="cim" /></h2> sorra kerül, akkor ide ennek az adatblokknak a <cim> elemében található tartalmat másolja: <h2>A HTTP protokollról</h2>.
Végül visszakerülünk a <xsl:template match="bejegyzesek"> definícióba, ami az iteráció után lezárja a megnyitott <div> elemünket.
Mindenkit bátorítok, hogy kezdjen el játszani a stíluslapokkal, viszonylag hamar rá lehet jönni a logikájukra, XSL referenciának a ZVON gyűjteményét ajánlom (magyar nyelvű).