Stworzymy prostą stronę internetową, gdzie wykorzystamy XML do obiegu danych w naszym systemie. Stworzymy parę bardzo prostych funkcji, dzięki którym usprawnimy naszą pracę z dokumentami.
Wymagania:
Podstawowa znajomość XML i XSL oraz dobra znajomość PHP na poziomie obiektów.
Struktura:
Tworzymy pliki oraz foldery:
- /index.php
- /class/core.php
- /xsl/index.xsl
Obiekt danych w XML’u:
W naszym pliku core.php musimy stworzyć obiekt Data, który będzie trzymał w sowim obiekcie dane w postaci XML DOM. Jako że postawiłem na wymóg znajomość PHP to wszelakie funkcje w kodzie które są komentowane można, a nawet należy sobie rozszerzyć z manualem PHP.
class Data { public $doc = null; public $root = null; public function __construct() { $this->doc = new DOMDocument('1.0', 'UTF-8'); //tworzymy dokument xml do ktorego bedziemy wstawiać dane $this->root = $this->doc->createElement('main'); //tworzymy element podstawowy tzn. root element $this->doc->appendChild($this->root); //wstawiamy uprzednio stworzony węzeł main w dokument } public function setData($element, $value=NULL){ if($value==NULL)//sprawdzamy czy wartość nie jest null { $node = $this->doc->createElement($element); //wartość jest pusta więdz tworzymy tylko węzel bez wartości $this->root->appendChild($node); //wstawiamy węzeł w główny węzeł root stworzony w konstruktorze } else { $node = $this->doc->createElement($element, $value); //wartość nie jest pusta więdz tworzymy węzeł odrazu z wartością $this->root->appendChild($node); //wstawiamy w głowny wezeł } } public function showXML(){ header("Content-type: text/xml; charset=utf-8"); echo $this->doc->saveXML(); } }
Transformacja po stronie serwera:
W naszym pliku core.php musimy stworzyć kolejny obiekt, który będzie nam transformował dokument(XML) wygenerowany z wybranym szablonem(XSL).
class View { private $name=NULL; private $data=NULL; public function setView($name, $data) { $this->name = $name; //ustawiamy nazwę naszego szablonu $this->data = $data; //ustawiamy przekazany obiekt naszych danych } public function showView($transform = null) { $templateFileName = "xsl/".$this->name.".xsl"; //tworzymy ścieszkę do pliku szablonu $xsl = new DomDocument; //tworzymy obiekt do przechowywania szablonu $xsl->load($templateFileName); //ładujemy nasz szablon do obiektu $xslt = new xsltprocessor; //tworzymy obiekt procesora XSLT $xslt->importStyleSheet($xsl); //importujemy obiekt z uprzednio popranym plikiem szablonu $wynik=$xslt->transformToXML($this->data->doc); //wykonujemy transformację 2 dokumentów print($wynik); //wyświetlamy wynik transformacji } }
Dane
Następnym krokiem będzie skorzystanie z naszych obiektów w celu umieszczenia w nich odpowiednich danych. W tym celu w naszym pliku index.php umieszczamy poniższy kod.
include("class/core.php"); $data = new Data(); $view = new View; $data->setData('title', 'XML i XSLT jako system szablonów w PHP'); $data->setData('logo', 'Strona Główna'); $data->setData('stopka', 'Wszelkie prawa zastrzeżone © 2009.'); $data->showXML();
Metoda setData klasy Data umieszcza nam dane w dokumencie. Z kolei metoda showXML prezentuje dokument który stworzyliśmy. Uruchamiając naszą stronę przez interpreter PHP ujrzymy dokument XML. Jak widać nie możemy tworzyć zagnieżdżeń zbyt głęboko.
Rozbudujemy teraz metodę set data by mogła przyjmować tablice asocjacyjne.
public function setData($element, $value=NULL){ if($value==NULL) //sprawdzamy czy wartość nie jest null { $node = $this->doc->createElement($element); //wartość jest pusta więdz tworzymy tylko węzel bez wartości $this->root->appendChild($node); //wstawiamy węzeł w główny węzeł root stworzony w konstruktorze } elseif($value!=NULL && is_string($value)) { $node = $this->doc->createElement($element, $value); //wartość nie jest pusta więdz tworzymy węzeł odrazu z wartością $this->root->appendChild($node); //wstawiamy w głowny wezeł } elseif(is_array($value)) //jesli wartość jest tablica { $node = $this->doc->createElement($element); $this->root->appendChild($node); foreach($value as $klucz => $var){ if(is_array($var)){ $subnode = $this->doc->createElement($klucz); $node->appendChild($subnode); foreach($var as $klucz => $var){ $subnode->appendChild($this->doc->createElement($klucz, $var)); } }else{ $node->appendChild($this->doc->createElement($klucz, $var)); } } } }
Od teraz metoda będzie mogła przyjmować tablice asocjacyjne do drugiego stopnia zagnieżdżenia. Kolejne stopnie zagnieżdżenia tablic niema większego sensu w tym celu zachęcam do lektury na temat serializacji obiektów bądź rozbudowy metody setData tak by przyjmowała obiekt XML DOM.
Rozbudujmy jeszcze index.php o kilka niezbędnych danych korzystając już z dobrodziejstw tablic. Dodajmy poniższy kod pod nasze wcześniejsze set data.
$dane['artykul'] = array('tytul' => 'Strona Tytułowa', 'tekst' => 'Jakaś treść', 'data' => '15 kwietnia 2009 roku 15:18'); $data->setData('dane', $dane);
Szablon podstawowy
Stworzymy teraz szablon, który będziemy importować do innych szablonów, będzie nam on pomocny gdyż wszystkie strony będą podobne. Zmianie zazwyczaj nie ulegają takie elementy jak logo czy stopka. Ponadto chodzi również o takie elementy jak znaczniki meta czy formę wyjściową definiowana poprzez xsl:output.
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > <xsl:output method="xml" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" /> <xsl:template match="/"> <html> <head> <title> <xsl:value-of select="main/title" /> </title> </head> <body> <h1><xsl:value-of select="main/logo" /></h1> <xsl:apply-templates /> <p><xsl:value-of select="main/stopka" /></p> </body> </html> </xsl:template> </xsl:stylesheet>
Tworzymy w naszym katalogu xsl plik main.xml. I uzupełniamy go w poniższy sposób.W tym przypadku mamy szkielet dokumentu html. Dzięki xsl:apply-templates będziemy mogli wszystkie pozostałe węzły dopasowywać i umieszczać w odpowiednim miejscu.
Szablony stron
Następnym krokiem, będzie wypełnienie odpowiednim kodem uprzednio stworzonego pliku szablonu jakim jest index.xsl. W tym szablonie będziemy importować szablon podstawowy i zajmować się tylko danymi, które mają znaleźć się pomiędzy logiem a stopką strony.
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:import href="main.xsl"/> <xsl:template match="main"> </xsl:template> </xsl:stylesheet>
Widzimy xsl:import który importuje nam do aktualnego szablonu plik main.xsl. Następnie xsl:template zaczyna stosować szablon zaczynając od węzła main, który przyjmuje wartość w parametrze match. Zmodyfikujmy nasz szablon dodając wewnątrz xsl:template następujący kod.
<div> <h3><xsl:value-of select="dane/artykul/tytul" /></h3> <hr /> <p><xsl:value-of select="dane/artykul/tekst" /></p> <em><xsl:value-of select="dane/artykul/data" /></em> </div>
Teraz już wykorzystujemy wszystkie dane które utworzyliśmy dzięki obiektowi Data w index.php.
Widok
Nadszedł czas by nasz system szablonów zaczął działać w tym celu skorzystamy z uprzednio utworzonej klasy View.
Wyrzucamy z pliku index.php linie $view->showView(); gdyż służyła nam ona tylko po to byśmy widzieli jaką strukturę dokumentu XML tworzyliśmy. W jej miejsce wkleimy poniższy kod.
$view->setView('index', $data); $view->showView();
Metoda setView w pierwszym parametrze przyjmuje nazwę szablonu do transformacji znów w drugim parametrze zostaje przekazany obiekt data z naszymi danymi. Z kolei, metoda showView wykonuję transformację dokumentów i zwraca dokument określony w szablonie za pomocą xsl:output.
Śmiało można teraz uruchomić przeglądarkę i zobaczyć wynik naszej pracy. Wbudowany w PHP procesor xslt zwrócił nam ładną stronę w postaci xhtml, ponadto warto zauważyć ze również importował plik main.xsl i wykonał w nim instrukcje.
Podsumowanie
Mam nadzieję, że udało mi się ukazać drogę w która należy iść. Warto się zainteresować takimi terminami jak singleton czy serializacja. Bardzo ciekawy efekt daje tez tworzenie xml’a z wyników zapytań do bazy danych automatyzuje wiele żmudnych czynności i zrzuca je na obsługę w szablonie. Ponadto można zrobić świetne buforowanie trzymając pliki xml i skazując przeglądarkę klienta na transformowanie ich bądź jeśli przeglądarka nie obsługuje takich metod transformować je już z wygenerowanych plików xml trzymanych w buforze.







