XSLT a gyakorlatban
Az XSLT használata sablonnyelvként
Miután rájöttem, hogy minden olyan sablon-nyelv használata, amely nyelv nem egyezik meg az éppen használttal, felesleges időfecsérlés, itt volt az ideje, hogy írjak valamit XSLT-vel kapcsolatban. Szóval ha az ember olyan trendi dolgokat használ, mint az MVC, akkor felmerül rá az igény, hogy élete megkönnyítése és a megjelenítő modul megfelelő általánosítása miatt jobb esetben használatba vegyen valami létező sablon-nyelvet, rosszabb esetben írjon egy sajátot. Az XSLT egy kézenfekvő megoldás lehet (mint azt valamikor a régmúltban már kifejtettük), mivel HTML (vagyis inkább XML) szerű, ezért - szerintem - valamivel emberközelibb egy HTML-t ismerő ember számára, mint mondjuk a beágyazott PHP függvények. Emellett, ha a dolgot PHP oldalról közelítjük meg, az XSLT feldolgozására egy egész kiterjesztés áll (vagy éppen nem áll) rendelkezésünkre, minek segítségével pár sorban el tudjuk intézni az oldal generálását.
A dolog esetünkben úgy néz ki, hogy létezik egy template.xml és egy template.xsl. A template.xml-ben találhatóak az alapértelmezett adatok (vagy csak az alapértelmezett adatszerkezet üresen), a template.xsl pedig maga a sablon, amire ráhúzzuk a template.xml segítségével az adatokat. Ennek a megoldásnak az előnye, hogy így az adatokat egyszerűen XPath segítségével (ami szintén beépített támogatást élvez PHP-ben) pofonegyszerűen tudjuk majd átadni az XSLT feldolgozónak. Nézzük a példafájlokat:
template.xml
<?xml version="1.0" encoding="utf-8"?>
<content>
<title value=""/>
<url value=""/>
<content><![CDATA[]]></content>
</content>
template.xsl
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="hu">
<head>
<title><xsl:value-of select="content/title/@value"/></title>
</head>
<body>
<h1><a href="{content/url/@value}"><xsl:value-of select="content/title/@value"/></a></h1>
<p><xsl:value-of select="content/text" disable-output-escaping="yes"/></p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Igazából innentől már csak egy minimális PHP kód következik, ami előre definiált adatok alapján (a $transformation tömb, amit a feldolgozó modul elég sok módon megkaphat) feltölti a betöltött template.xml-t adatokkal és a template.xsl segítségével elkészíti a kívánt formátumot:
/*
'Tartalom' betöltése
*/
$content_xsl = &DOMDocument::load('template.xsl');
$content = &DOMDocument::load('template.xml');
$content_xpath = &new DOMXPath($content);
$transformation['/content/title/@value'] = 'Valami cím';
$transformation['/content/url/@value'] = 'http://www.something.com/';
$transformation['/content/content/text()'] = 'Valami szöveg...';
/*
Transzformációk végrehajtása
*/
foreach ($transformation as $path => $value) {
if (!is_array($value)) {
$content_xpath->query($path)->item(0)->nodeValue = $value;
}
else {
foreach ($value as $key => $node) {
$content_node = $content->importNode($node, true);
$content_xpath->query($path)->item(0)->appendChild($content_node);
}
}
}
$proc = &new XSLTProcessor();
$proc->importStylesheet($content_xsl);
print $proc->transformToDoc($content)->saveXML();
A lényeg a $transformation tömb megadása, ami a feljebb betöltött XML fájlt alakítja át. Ahogy az a foreach ciklusban látszik, két fajta értéket adhatunk az XPath szerű asszociatív hozzárendelésnek. Sima stringet, vagy egy tömböt. Tömb esetén a tömbelemek értékei DOMDocument típusúak kell, hogy legyenek.
A dolog legnagyobb szépsége viszont az, hogy ha a template.xsl-t lecseréljük, de minden mást változatlanul hagyunk, akkor például HTML helyett generálhatunk akár RSS-t is:
template.xsl
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:template match="/">
<rss version="2.0">
<channel>
<title>Teszt RSS</title>
<link>http://www.something.com/</link>
<description>Ez egy teszt fájl a teszt RSS-nek...</description>
<item>
<title><xsl:value-of select="content/title/@value"/></title>
<link><xsl:value-of select="content/url/@value"/></link>
<description><xsl:value-of select="content/content/text()"/></description>
</item>
</channel>
</rss>
</xsl:template>
</xsl:stylesheet>
De szép az élet így, ha van valami, ami eléggé megkönnyíti (persze a header-rel még egy csepp gond van így ebben az esetben, de az most lényegtelen). Nosza, lehet nekiállni a régi és megunt rendszeredet XSLT alapokra helyezni, mert az - ahogy a fenti példa is mutatja - jó. De természetesen ízlés kérdése. Ha az ember csak egy saját kis oldalt fejlesztget, és tudja, hogy más nem fog belenyúlni a sablonokba, akkor igazából a PHP, mint sablon-nyelv is tökéletesen megfelel a célra. Tehát: használja, aki úgy érzi, hogy szüksége van rá.