background image

01/2008

Narzędzia

54

XSLT

www.phpsolmag.org

55

X

SLT (ang. eXtensible Stylesheet Lan-
guage  Transformations)
  to  język 
transformacji  dokumentów  XML. 

Za  jego  pomocą  możemy  więc  przetrans-
formować  dane  XML  w  jakąś  inną  postać, 
na  przykład  w  dokument  HTML.  To  nato-
miast  otwiera  przed  nami  szereg  nowych 
opcji związanych z oddzieleniem treści stro-
ny od tagów HTML, możliwością generowa-
nia  jak  i  wykorzystania  plików  XML  przez 
inne  aplikacje  webowe  (mobilność  danych) 
i nie tylko. Zalety i wady XSLT przedstawi-
my jednak trochę później. Aby łatwiej było 
nam  zrozumieć  całą  ideę  i  sens  stosowania 
transformacji  XSL,  zaczniemy  od  prostego 
przykładu,  omawiając  jednocześnie  podsta-
wy tego języka.

Metoda 1. – XML + XSL

Pierwszym przykładem wykorzystania trans-
formacji XSL jest strona przedstawiająca spis 
użytkowników serwisu wraz z kilkoma pod-
stawowymi  informacjami  o  nich.  Stwórzmy 
więc plik 

users.xml 

o treści zaprezentowa-

nej na Listingu 1. Kod jest tutaj bardzo pro-
sty – niejasne mogą być jedynie dwie pierw-
sze  linijki.  Pierwsza  to  nagłówek  informują-
cy o tym, że jest to plik XML (oraz ustalający 
jego kodowanie). Druga natomiast jest odno-

śnikiem do pliku XSL, który za chwilę stwo-
rzymy. Dalsza część kodu to podstawowe in-
formacje  o  użytkownikach:  nazwa  użytkow-
nika  (

nick

), 

wiek 

(age), 

ranga 

(rank)  oraz 

ilość  postów  na  wyimaginowanym 

forum

 

(posts).  Na  Listingu  1.  zamieściliśmy  tylko 
trzech użytkowników,  ale  ich  liczba  oczywi-
ście może być dowolna.

Mamy  więc  dane,  które  chcemy  wyświe-

tlić.  Drugim  krokiem  jest  stworzenie  pliku 
XSL mówiącego przeglądarce jak te dane po-
winny zostać wyświetlone. Aby ułatwić zro-
zumienie  tego  procesu  dodajmy,  że  XSL  dla 
plików  XML  jest  tym  samym  czym  CSS  dla 
HTML.  Można  więc  plik  XSL  nazwać  arku-
szem  stylów,  jednak  jego  kod  potrafi  o  wie-
le  więcej  –  XSLT  posiada  struktury  znane 
z  języków  funkcyjnych,  jak  na  przykład  pę-
tle, czy instrukcje warunkowe. Plik XSL daje 
więc  nam  pełną  kontrolę  nad  generowanym 
kodem strony.

Stwórzmy plik 

users.xsl

, którego kod znaj-

duje się na Listingu 2. Trzy pierwsze linijki de-
klarują wersję i kodowanie pliku oraz informu-
ją, że jest to plik XSL. Element 

xsl:template 

tworzy  nowy  szablon,  który  (w  naszym  przy-
padku) zawiera cały właściwy kod generowanej 
strony. Jeden plik XSL może zawierać wiele sza-
blonów, a każdy z nich może dotyczyć zupełnie 
innej części drzewa pliku XML. 

W naszym przypadku szablon wskazuje na 

users (

<xsl:template match="users">

), czy-

li  element  zawierający  wszystkie  nasze  dane 
(jeśli  nie  wiesz  o  jakim  elemencie  mówimy, 
przyjrzyj się dokładnie plikowi 

users.xml

).

W  dalszej  części  kodu  przygotowujemy 

tabelkę  zawierającą  informacje  pobrane  ze 
stworzonego  wcześniej  pliku  XML.  Zwróć-
my szczególną uwagę na kod zawarty pomię-
dzy 

<xsl:for-each  select="user">  a  </

xsl:for-each>

. Jest to pętla podobna do fore-

ach (znanej z PHP) – iteruje przez wszystkie 
elementy  o  nazwie  user  dostarczając  zawar-
tych w nich danych, które natomiast umiesz-
czamy  w  odpowiednich  miejscach  wiersza 
tabelki.  Dokonujemy  tego  za  pomocą 

<xsl:

value-of select="dziecko"/>

, gdzie dziec-

ko to nazwa elementu znajdującego się w ele-
mencie 

user

.

W  tym  miejscu  pragniemy  zwrócić  uwa-

gę  czytelnika  na  sposób  pobierania  wartości 

XSLT

Transformacje XSL to bardzo potężne i przydatne narzędzie, za pomocą 

którego możemy m.in. łatwo oddzielić treść strony od kodu określającego 

jej  wygląd,  zapewniając  sobie  możliwość  wykorzystania  tych  samych 

danych w różny sposób.

Dowiesz się...

•   Co to jest XSLT i jak się tego używa;
•   Poznasz różne metody wykorzystania XSLT;
•   Poznasz wady i zalety transformacji XSL;
•   Dowiesz się jak zoptymalizować generowanie 

stron internetowych.

Powinieneś wiedzieć...

•   Posiadać  znajomość  języków  XML,  XHTML 

oraz PHP;

•   Mieć doświadczenie w programowaniu stron z 

wykorzystaniem DOM.

Poziom trudności

Czy warto zamienić HTML na XML ?

Listing 1. Zawartość pliku users.xml 
prezentującego listę użytkowników strony

<

?xml version=

"1.0"

 

encoding=

"UTF-8"

?

>

<

?xml-stylesheet type=

"text/xsl"

 

                 

href=

"users.xsl"

?

>

<

users

>

<

user

>

<

nick

>

admin

<

/nick

>

<

age

>

23

<

/age

>

<

rank

>

Administrator

<

/rank

>

<

posts

>

190

<

/posts

>

<

/user

>

<

user

>

<

nick

>

abc

<

/nick

>

<

age

>

19

<

/age

>

<

rank

>

Ekspert

<

/rank

>

<

posts

>

1240

<

/posts

>

<

/user

>

<

user

>

<

nick

>

xyz123

<

/nick

>

<

age

>

15

<

/age

>

<

rank

>

Początkujący

<

/rank

>

<

posts

>

3

<

/posts

>

<

/user

>

<

/users

>

background image

01/2008

Narzędzia

54

XSLT

www.phpsolmag.org

55

poszczególnych elementów pliku XML. Przy 
bardziej  skomplikowanych  szablonach  waż-
ne  jest  rozumienie  takich  pojęć  jak:  dziec-
ko (ang. child), rodzic (parent), przodek (ance-
stor
),  potomek  (descendant)  itd.  Jest  to  bezpo-
średnio związane z faktem, że XSLT do wska-
zywania na różne części dokumentu wykorzy-
stuje język XPath. 

Dlatego też, jeśli czytelnik nie jest zazna-

jomiony  z  wyżej  wymienionymi  pojęciami, 
polecamy lekturę stron traktujących o tej te-
matyce  –  ich  adresy  zamieszczamy  w  ram-
ce W Sieci.

Korzystając  z  okazji,  chcielibyśmy  także 

wspomnieć  o  jeszcze  jednym,  powiązanym 
z  naszym  tematem  (a  dokładniej  z  XML), 
standardzie  W3C.  Jest  nim  XML  Sche-
ma  Definition  –  w  skrócie  XSD  (lub  XML 
Schema
). Służy on do definiowania struktu-
ry dokumentu XML. Czytelnikom zaznajo-
mionym  z  DTD  dodamy,  że  XSD  jest  uwa-
żany za jego następcę. Wszystkich zaintere-
sowanych tym tematem ponownie odsyłamy 
do ramki W Sieci.

Teraz  możemy  sprawdzić  efekty  naszych 

działań.  Zobaczymy  je  uruchamiając  stro-
nę 

users.xml

  w  przeglądarce  interneto-

wej  (możemy  to  zrobić  lokalnie;  nie  ma 
potrzeby  umieszczania  plików  na  serwe-
rze). Oczom naszym ukaże się prosta tabel-
ka  przedstawiająca  informacje  o  fikcyjnych 
użytkownikach zmyślonego serwisu. 

Pierwszy  krok  w  stronę  poznania  XSLT 

mamy  więc  za  sobą.  Jak  widać  na  powyż-
szym  przykładzie,  aby  opanować  umiejęt-
ność  efektywnego  korzystania  z  transfor-
macji  XSL,  musimy  -  poza  zdolnością  wy-
obrażania sobie dokumentu XML jako drze-
wa  elementów  (co  jest  pośrednio  związane 
ze  znajomością  wspomnianego  wcześniej 
XPath) – poznać tylko kilka podstawowych 
reguł i definicji w nim panujących. Z trzema 
jesteśmy już zaznajomieni – pojęcie szablo-
nu  (

xsl:template

),  pętli  (

xsl:for-each

oraz pobierania wartości (

xsl:value-of

 ).

Metoda 2. – PHP + XML + XSL

Uważni  czytelnicy  studiując  poprzedni 
przykład, być może zwrócili uwagę na fakt, 
że  wynikowy  kod  strony  (kod  HTML)  jest 
generowany  w  locie.  Faktycznie,  w  dodat-
ku  dokonuje  tego  przeglądarka  interneto-
wa  użytkownika.  Ma to  swój  plus (odciąże-
nie serwera), jak i minus (ryzyko niekompa-
tybilności). 

O  wadach  i  zaletach  powiemy  nieco  póź-

niej;  teraz  zaprezentujemy  drugi  sposób  wy-
korzystania  XSLT,  w  którym  brzemię  gene-
rowania  kodu  wynikowego  przerzucimy  na 
serwer.

PHP od wersji 5_ ma wbudowane wspar-

cie dla transformacji XSL (serwer PHP mu-
si być uruchomiony z opcją –

with-xsl

, a w 

systemie  konieczna  jest  obecność  bibliote-

ki 

libxslt

  –  więcej  informacji  na  ten  te-

mat zamieściliśmy w ramce Instalacja XSLT 
w PHP5). 

Możemy  więc  bez  problemu  wygenero-

wać  kod  HTML  i  wysłać  go  do  przeglądar-
ki użytkownika. Taką właśnie metodę wyko-
rzystamy w drugim przykładzie. Potrzebuje-
my  tylko  jednego  dodatkowego  pliku  PHP, 
w którym dokonamy transformacji. Nazwij-
my go users.php. Kod PHP wraz z komenta-
rzami przedstawia Listing 3.

Czynności zawarte na tym Listingu spro-

wadzają  się  do  wczytania  pliku  XML  oraz 
XSL (do tego celu wykorzystujemy jeden ze 
standardowo  dostępnych  modułów  PHP5, 
zwany  po  prostu  Document  Object  Model 
–  DOM
),  dokonania  transformacji  i  osta-
tecznie wysłania efektu końcowego do prze-
glądarki. Widzimy więc, że całą pracę wyko-
nuje za nas PHP (a dokładniej obiekt XSLT-
Processor).

Tego  przykładu  oczywiście  nie  możemy 

sprawdzić  lokalnie,  chyba  że  mamy  uru-
chomione środowisko z obsługą PHP. W in-
nym przypadku musimy przesłać wszystkie 
trzy pliki na serwer, a następnie otworzyć w 
przeglądarce stronę users.php. Rezultat z te-
go jak i poprzedniego przykładu wydaje się 
być  taki  sam,  jednak  wszystko  się  zmienia, 
gdy  zajrzymy  do  kodu  źródłowego  strony. 
Możemy  przekonać  się  na  własne  oczy,  że 
w pierwszym przypadku kod strony to plik 
XML,  a  w  drugim  (wygenerowanym  przez 
PHP) rezultatem jest zwykły HTML.

Druga metoda zapewnia nam pełną kom-

patybilność z przeglądarkami nieobsługują-
cymi  XSLT,  jednak  każdorazowe  generowa-
nie strony w większym stopniu obciąża ser-
wer.  Pierwsza  metoda  nie  dokonuje  dodat-
kowego narzutu, lecz decydując się na stoso-
wanie jej musimy pamiętać, że użytkownik 
posiadający  niekompatybilną  przeglądarkę 
nie będzie mógł korzystać z naszej strony.

Wyjścia z tej sytuacji są co najmniej dwa. 

W dodatku oba mogą być stosowane jedno-
cześnie. Przestudiujemy je dokładnie trochę 
później, teraz zaprezentujemy jeszcze jeden 
– prawdopodobnie najbardziej interesujący 
– sposób wykorzystania transformacji XSL.

Metoda 3. 

– MySQL + PHP + XSL

Używanie  XSLT  mijałoby  się  z  celem,  gdy-
byśmy  musieli  ręcznie  tworzyć  pliki  XML 
zawierające  treść  naszych  stron.  Czemu 
nie  generować  takich  plików  automatycz-
nie,  pozyskując  dane  z  bazy  MySQL?  Przy 
przemyślanej  konstrukcji  serwisu  taka  me-
toda zapewni nam dużą elastyczność w spo-
sobie  wyświetlania  danych,  nie  pociągając 
za sobą konieczności ingerencji w kod PHP. 
Sprawdźmy więc, jak to wygląda w praktyce. 

Naszym  pierwszym  krokiem  jest  stwo-

rzenie  tabeli  w  bazie  danych  oraz  zapełnie-

nie  jej  fikcyjnymi  informacjami.  Stwórzmy 
więc teraz za jego pomocą nową tabelę w ba-
zie danych.

Następną czynnością jest napisanie skryp-

tu PHP, który pobierze dane, wygeneruje na 
ich  podstawie  plik  XML,  dokona  transfor-

Listing 2. Plik users.xsl dokonujący 
formatowania danych XML

<

?xml version=

"1.0"

 

encoding=

"UTF-8"

?

>

<

xsl:stylesheet version=

"1.0"

xmlns:xsl=

"http://www.w3.org/1999/XSL/

Transform"

>

 

<

xsl:template match=

"users"

>

<

html

>

<

body

>

<

h2

>

Lista użytkowników

<

/h2

>

<

table

>

<

tr

>

<

th

>

Nazwa

<

/th

>

<

th

>

Wiek

<

/th

>

<

th

>

Ranga

<

/th

>

<

th

>

Postów

<

/th

>

<

/tr

>

<

xsl:for-each select=

"user"

>

<

tr

>

<

td

><

xsl:value-of select=

"nick"

/

><

/td

>

<

td

><

xsl:value-of select=

"age"

/

><

/td

>

<

td

><

xsl:value-of select=

"rank"

/

><

/td

>

<

td

><

xsl:value-of select=

"posts"

/

><

/td

>

<

/tr

>

<

/xsl:for-each

>

<

/table

>

<

/body

>

<

/html

>

<

/xsl:template

>

<

/xsl:stylesheet

>

Listing 3. Plik users.php generujący kod 
HTML na podstawie dwóch poprzednich 
plików

<?

php

// Wczytujemy plik XML

$xml 

=

 new DOMDocument

(

'1.0'

'UTF-8'

)

;

$xml

->

load

(

'users.xml'

)

;

 

// Wczytujemy arkusz XSL

$xsl

 = 

new DOMDocument

(

'1.0'

,

 

'UTF-8'

)

;

$xsl

->

load

(

'users.xsl'

)

;

 

// Podczepiamy arkusz XSL

$proc

 

=

 

new XSLTProcessor

;

$proc

->

importStyleSheet

(

$xsl

)

;

 

// Wyświetlamy kod HTML wygenerowany na 

podstawie pliku 
XML i arkusza 
XSL

echo 

$proc

->

transformToXML

(

$xml

)

;

?>

 

background image

01/2008

Narzędzia

56

XSLT

www.phpsolmag.org

57

macji  XSL  oraz  wyśle  rezultat  do  przeglą-
darki użytkownika. Wszystkie te czynności 
wykonuje kod zawarty na Listingu 4.

Poza  nawiązaniem  połączenia  z  bazą  da-

nych  (linijka  4.  –  nie  zapomnij  wstawić 
swoich  danych!),  pobraniem  informacji  za-
pisanych  w  tabelce  users  (za  pomocą  me-
tody 

$mysqli->query()

)  oraz  generowa-

niem  kodu  wyjściowego  (trzy  ostatnie  blo-
ki kodu) , znanym z poprzedniego przykładu, 
ten skrypt dokonuje jeszcze jednej, bardzo waż-
nej rzeczy. Jest nią oczywiście tworzenie doku-
mentu XML na podstawie danych z bazy My-
SQL,  który  zostaje  następnie  użyty  do  wyge-

nerowania  rezultatu  końcowego  w  postaci 
strony  HTML.  Dość  intensywnie  używamy 
w tym kodzie metod 

createElement()

 oraz 

appendChild()

.  O  ile  nazwa  tej  pierwszej 

mówi  wszystko,  o  tyle  druga  może  wydać 
się  niejasna.  Metoda 

appendChild()

  wsta-

wia  nowy  węzeł  do  struktury  (drzewa)  na-
szego  pliku  XML.  Jako  argument  pobiera 
element, który zostanie podczepiony do wę-
zła wywołującego tę metodę. Tym sposobem 
umieszczamy  wszystkie  informacje  o  da-
nym  użytkowniku  do  elementu 

user

,  któ-

ry  natomiast  wstawiamy  do  węzła  główne-
go – 

users

.

W  tym  miejscu  chcielibyśmy  raz  jesz-

cze  odciągnąć  uwagę  czytelnika  od  właści-
wego  tematu  artykułu  i  krótko  wspomnieć 
o  pewnym  dodatkowym  narzędziu,  któ-
re  warto  znać.  Jest  nim  SimpleXML  -  mo-
duł  standardowo  dostępny  w  PHP  od  wer-
sji  5.  SimpleXML  okazuje  się  niezastąpiony 
we  wszelkich  działaniach  na  danych  w  for-
macie XML, a te –jak wiemy –są nieodzow-
ną  częścią  programowania  z  wykorzysta-
niem  XSLT.  Korzystanie  z  SimpleXML  jest 
(jak sama nazwa wskazuje) proste –aby jed-
nak zapewnić czytelnikowi przyjemny start, 
w ramce W Sieci podajemy adresy stron opi-
sujących to narzędzie.

Metoda trzecia kryje w sobie z pewnością 

największą  moc  i  ukazuje  prawdziwą  potę-
gę drzemiącą w XSLT. Jako że nasza wiedza 
o  transformacjach  XSL  przybrała  już  dosyć 
sensowne  kształty,  czas  ją  sobie  porządnie 
usystematyzować. Dlatego też zajmiemy się 
teraz  omówieniem  wad  i  zalet  każdej  z  po-
znanych metod użytkowania XSLT. Następ-
nie porównamy możliwości tej nowo pozna-
nej  techniki  ze  sposobem,  którego  używali-
śmy wcześniej, a mianowicie z ręcznym two-
rzeniem kodu HTML formatowanym za po-
mocą arkuszy stylów CSS. Wbrew pozorom 
żadna  z  tych  metod  nie  jest  lepsza  od  dru-
giej -- każda ma plusy i minusy. Ważne jest 
więc,  aby  wybrać  odpowiednią  dla  dane-
go  projektu.  W  nieco  dalszej  części  artyku-
łu  postaramy  się  pomóc  dokonać  prawidło-
wego wyboru.

Wady i zalety

przedstawionych metod

Nie  ma  róży  bez  kolców,  a  XSLT  nie  jest  pod 
tym  względem  wyjątkiem.  Dotychczas  omó-
wiliśmy  trzy  metody  wykorzystania  transfor-
macji XSL. Pierwsza polega na stworzeniu pli-
ku XML zawierającego treść strony oraz pliku 
XSL formatującego tą treść. Plik XML posiada 
również odnośnik do arkusza XSL, dzięki cze-
mu przeglądarka wie jak ma wygenerować stro-
nę.  Ważną  zaletą  tej  metody  z  pewnością  jest 
brak obciążenia serwera, ponieważ cały proces 
generowania  odbywa  się  po  stronie  odwiedza-
jącego (client-side).

Niestety, jak to zazwyczaj bywa przy czyn-

nościach  odbywających  się  po  stronie  klien-
ta, transformacje XSL również mogą być nie-
obsługiwane przez przeglądarkę odwiedzają-
cego.  Radzi  sobie  z  nimi  bez  problemu  Mo-
zilla Firefox (i podobne), jak również Internet 
Explorer
 od wersji 6. Sytuacja jednak nie jest 
już  taka  różowa  w  przypadku  Opery  (ta  ofi-
cjalnie  wspiera  XSLT  od  wersji  9;  mimo  to 
wciąż zdarzają się jej dziwne problemy z for-
matowaniem), a jeszcze gorsza w przeglądar-
ce  Safari.  Zapewne  ten  stan  rzeczy  ulegnie 
zmianie  wraz  z  pojawianiem  się  następnych 
wersji  tych  przeglądarek,  jednak  nie  można 
lekceważyć tego problemu.

Listing 4. Plik users_database.php generujący kod XML na podstawie danych z bazy MySQL

<?

php

// Podajemy podstawowe informacje o połączeniu z bazą danych
// oraz ustawiamy kodowanie znaków

$mysqli

 = 

new

 mysqli

(

"localhost"

"nazwa_uzytkownika"

"haslo"

"nazwa_tabeli"

)

;

$mysqli

-

>

set_charset

(

"utf8"

)

;

 

// Pobieramy informacje o użytkownikach

$result

 = 

$mysqli

-

>

query

(

"SELECT * FROM `users`"

)

;

 

// Tworzymy dokument XML

$xml

 = 

new

 DomDocument

(

'1.0'

'UTF-8'

)

;

 

// Tworzymy główny węzeł

$users

 = 

$xml

-

>

createElement

(

'users'

)

;

$users

 = 

$xml

-

>

appendChild

(

$users

)

;

 

// Pobieramy jednego użytkownika i dodajemy informacje o nim do pliku XML

while

(

$row

 = 

$result

-

>

fetch_assoc

())

{

// Tworzymy gałąź 'user' zawierającą informacje o konkretnym użytkowniku

$user

 = 

$xml

-

>

createElement

(

'user'

)

;

$user

 = 

$users

-

>

appendChild

(

$user

)

;

// Dodajemy wszystkie informacje, 
                 tj. nick, wiek, ranga i liczba postów

foreach

(

$row

 as 

$fieldName

 =

>

 

$fieldValue

)

{

$child

 = 

$xml

-

>

createElement

(

$fieldName

$fieldValue

)

;

$child

 = 

$user

-

>

appendChild

(

$child

)

;

}
}

 

// Zamykamy zasoby bazy danych

$result

-

>

close

()

;

$mysqli

-

>

close

()

;

 

// Wczytujemy arkusz XSL

$xsl

 = 

new

 DOMDocument

(

'1.0'

'UTF-8'

)

;

$xsl

-

>

load

(

'users.xsl'

)

;

 

// Podczepiamy arkusz XSL

$proc

 = 

new

 XSLTProcessor;

$proc

-

>

importStyleSheet

(

$xsl

)

;

 

// Wyświetlamy kod HTML wygenerowany na podstawie pliku XML i arkusza XSL

echo

 

$proc

-

>

transformToXML

(

$xml

)

;

?>

background image

01/2008

Narzędzia

56

XSLT

www.phpsolmag.org

57

Rozwiązaniem  problemu  kompatybilno-

ści  jest  natomiast  metoda  druga,  polegająca 
na  przeniesieniu  ciężaru  generowania  stro-
ny  na  serwer  (server-side).  Przeglądarka  od-
wiedzającego dostaje w takim przypadku go-
towy kod HTML, z którego interpretacją nie 
może już mieć problemu. Rozwiązanie to jest 
wręcz przeciwstawne do metody pierwszej i 
to co jest plusem w jednej z nich staje się mi-

nusem  w  drugiej.  W  metodzie  drugiej  poja-
wia się więc problem obciążenia serwera, co 
trzeba mieć na uwadze, szczególnie przy du-
żej liczbie odwiedzin serwisu.

Metoda trzecia natomiast nie różni się pod 

względem  sposobu  generowania  kodu  wyj-
ściowego  od  metody  drugiej.  W  tym  przy-
padku  dochodzi  jeszcze  automatyczne  ge-
nerowanie dokumentu XML (który w meto-

dzie numer 2 jest wczytywany z pliku), co po-
woduje dodatkowy narzut obciążenia, z któ-
rym serwer musi się uporać w przyzwoitym 
czasie.

Zarówno w metodzie drugiej, jak i trzeciej, 

nie  dokonujemy  żadnych  optymalizacji  pod 
względem obciążenia serwera. Każde odświe-
żenie  strony  wywołuje  ponownie  proces  ge-
nerowania kodu, co nie jest najlepszym wyj-

Listing 5. Plik users_database_final.php posiadający omawiane optymalizacje

<?

php

// Sprawdzamy, czy przeglądarka obsługuje XSLT

$xslt

 = 

(

strpos

(

$_SERVER

[

'HTTP_USER_AGENT'

]

'gecko'

)

     )
      

 

?

 true : false;

 

// Sprawdzamy datę ostatniego wygenerowania pliku XML

if

 

(

file_exists

(

'users.xml'

)

)

 

{

// Pliki są wystarczająco nowe, by z nich skorzystać

if

(

time

()

 

<

 filemtime

(

'users.xml'

)

 + 300

)
{

if

(

!

$xslt

)

echo

 file_get_contents

(

'users.html'

)

;

else

{

header

(

"Content-type: text/xml; charset=utf-8"

)

;

echo

 file_get_contents

(

'users.xml'

)

;

}

return

;

}
}

 

// Pliki nie zostały stworzone lub są stare

 

// Podajemy podstawowe informacje o połączeniu z bazą danych
// oraz ustawiamy kodowanie znaków

$mysqli

 = 

new

 mysqli

(

"localhost"

"nazwa_uzytkownika"

"haslo"

"nazwa_tabeli"

)

;

$mysqli

-

>

set_charset

(

"utf8"

)

;

 

// Pobieramy informacje o użytkownikach

$result

 = 

$mysqli

-

>

query

      

(

"SELECT * FROM `users`"

)

;

 

// Tworzymy dokument XML

$xml

 = 

new

 DomDocument

(

'1.0'

'UTF-8'

)

;

$xml

-

>

appendChild

(

$xml

-

>

createProcessingInstruction

(

'xml-stylesheet'

'href="users.xsl" type="text/xsl"'

)
)

;

 

// Tworzymy główny węzeł

$users

 = 

$xml

-

>

createElement

(

'users'

)

;

$users

 = 

$xml

-

>

appendChild

(

$users

)

;

 

// Pobieramy jednego użytkownika i dodajemy informacje o nim 

do pliku XML

while

(

$row

 = 

$result

-

>

fetch_assoc

())

{

// Tworzymy gałąź 'user' zawierającą informacje o konkretnym 

użytkowniku

$user

 = 

$xml

-

>

createElement

(

'user'

)

;

$user

 = 

$users

-

>

appendChild

(

$user

)

;

 

// Dodajemy wszystkie informacje, tj. nick, wiek, ranga i 

liczba postów

foreach

(

$row

 as 

$fieldName

 =

>

 

$fieldValue

)

{

$child

 = 

$xml

-

>

createElement

(

$fieldName

$fieldValue

)

;

$child

 = 

$user

-

>

appendChild

(

$child

)

;

}
}

 

// Zamykamy zasoby bazy danych

$result

-

>

close

()

;

$mysqli

-

>

close

()

;

 

// Zapisujemy kod XML do pliku users.xml

$xmlString

 = 

$xml

-

>

SaveXML

()

;

file_put_contents 

(

'users.xml'

$xmlString

)

;

 

// Brak obsługi XSLT, generujemy kod wyjściowy

if

(

!

$xslt

)

{

// Wczytujemy arkusz XSL

$xsl

 = 

new

 DOMDocument;

$xsl

-

>

load

(

'users.xsl'

)

;

 

// Podczepiamy arkusz XSL

$proc

 = 

new

 XSLTProcessor;

$proc

-

>

importStyleSheet

(

$xsl

)

;

 

// Zapisujemy wygenerowany kod HTML do pliku users.html

$result

 = 

$proc

-

>

transformToXML

(

$xml

)

;

file_put_contents 

(

'users.html'

$result

)

;

}

 

// XSLT jest obsługiwane

else

{

header

(

"Content-type: text/xml; charset=utf-8"

)

;

$result

 = 

$xmlString

;

}

 

// Wyświetlamy stronę

echo

 

$result

;

?>

background image

01/2008

Narzędzia

58

XSLT

www.phpsolmag.org

59

ściem. Oczywiście nie jesteśmy na nie skaza-
ni -- możemy dokonać cache’owania, co zresz-
tą będzie naszym celem nieco później.

Kolejnym  wyjściem  z  tej  sytuacji  jest  po-

łączenie  metody  pierwszej  i  drugiej.  Może-
my  więc  rozpoznawać  przeglądarkę  użyt-
kownika,  i  na  podstawie  tej  informacji  wy-
bierać odpowiednią metodę generowania na-
szej strony. Dzięki temu zarówno pozbędzie-
my  się  problemu  niekompatybilności  oraz 
znacznie  odciążymy  serwer  (Firefox  i  Inter-
net  Explorer
  posiadają  znakomitą  większość 
rynku  przeglądarek,  a  obsługują  one  w  peł-
ni XSLT), a po wprowadzeniu systemu cache-
’owania 
zmniejszymy obciążenie do całkiem 
znośnej wartości. 

Wszystkie  te  czynności  dokonamy  w  dal-

szej  części  artykułu.  Skoro  jednak  jesteśmy 
już  przy  omawianiu  zalet  i  wad,  warto  po-
równać sens stosowania XSLT ze standardo-
wą metodą: HTML + CSS.

XSLT czy HTML?

Nieporównywalną  przewagą  transformacji 
XSL  nad  ręcznym  pisaniem  pliku  HTML 
jest całkowite oddzielenie treści od warstwy 
prezentacji.  Dzięki  temu,  że  nasze  dane  są 
w  formacie  XML,  a  nie  w  postaci  mieszan-
ki treści właściwej z tagami HTML, możemy 
dowolnie modyfikować strukturę strony nie 
dotykając nawet skryptów PHP. Stworzenie 
systemu  skórek  (theme'ów)  staje  się  wtedy 
bardzo  łatwe  i  wygodne.  Przemyślana  kon-

strukcja plików XML umożliwi nam nawet 
całkowite oddzielenie danych od serwisu in-
ternetowego. W takiej sytuacji możemy wy-
korzystywać  je  np.  w  aplikacji  desktopowej
niezależnie  od  aktualnej  struktury  i  wyglą-
du strony internetowej. 
Działa  to  w  obie  strony  –równie  dobrze  to 
aplikacja  desktopowa  może  generować  pli-
ki  XML  i  umieszczać  je  na  serwerze,  któ-
re  to  zostają  następnie  wykorzystane  przez 
serwis  internetowy.  Możliwości  wykorzy-
stania  transformacji  XSL  jest  tak  wiele,  jak 
wiele  jest  różnych  zastosowań  samych  pli-
ków XML.

Kolejną  zaletą  jest  fakt,  że  XSLT  posiada 

możliwości podobne do tych znanych z języ-
ków funkcyjnych. Zawiera on takie struktu-
ry jak instrukcja warunkowa, pętla, instruk-
cja 

choose

 (podobna do 

switch

 znanej m.in. 

z  PHP),  dzięki  czemu  za  pomocą  jednego, 
mądrze  skonstruowanego  arkusza  XSL  mo-
żemy  np.  generować  różne  podstrony  ser-
wisu  internetowego.  W  dodatku,  XSLT  nie 
ogranicza  nas  w  żaden  sposób  pod  wzglę-
dem formatowania kodu HTML za pomocą 
arkuszy stylów CSS.

Niestety, stosowanie XSLT pociąga za so-

bą dodatkowy narzut tak w postaci obciąże-
nia serwera, jak i pracy przy tworzeniu ser-
wisu. Ten pierwszy problem w dość dużym 
stopniu uda się nam zniwelować, jednak ob-
ciążenie będzie zawsze większe niż w przy-
padku zastosowania "czystego" HTML. Dla-

tego też, mimo ogromnych zalet, XSLT z re-
guły nie nadaje się do małych, prostych ser-
wisów  internetowych.  Napisanie  kilku  pli-
ków  HTML  potrwa  po  prostu  krócej  niż 
zaimplementowanie  całego  systemu  obsłu-
gującego  transformacje  XSL  po  stronie  ser-
wera i klienta. Ważna jest więc decyzja, czy 
tworzony  przez  nas  serwis  internetowy  bę-
dzie naprawdę korzystał z zalet XSLT.

Znamy więc trzy metody używania trans-

formacji XSL. Wady i zalety tych metod też 
już  poznaliśmy.  Teraz  gdy  mamy  już  solid-
ne  fundamenty  w  tematyce  XSLT,  może-
my  omówić  bardziej  skomplikowane  kwe-
stie  dotyczące  optymalizacji  i  kompatybil-
ności rozwiązania. W dalszej części tego ar-
tykułu  zajmiemy  się  rozbudową  ostatnie-
go  przykładu  (wykorzystującego  bazę  da-
nych).  Dodamy  do  niego  dwie  nowe  cechy 
–automatyczny wybór metody generowania 
strony  zależnie  od  przeglądarki  użytkowni-
ka  oraz  prosty  system  cache'owania  danych 
XML i HTML.

Optymalizacje

W  celu  ograniczenia  obciążenia  serwera  po-
stanowiliśmy  wdrożyć  do  naszego  ostatnie-
go  przykładu  prosty  system  cache'owania 
oraz  system  automatycznego  wyboru  meto-
dy generowania kodu zależnie od przeglądar-
ki użytkownika. Listing 5. przedstawia zmo-
dyfikowaną  wersję  pliku  users_database.php 
– wzbogaconą o te dwa elementy. Jako że jest 
to najbardziej skomplikowany kod w tym ar-
tykule, omówimy go sobie krok po kroku.

Skrypt  zaczynamy  od  zdefiniowania 

zmiennej 

$xslt

. Do naszych potrzeb wystar-

czy,  że  sprawdzimy  ciąg 

HTTP_USER_AGENT 

pod  względem  frazy  gecko  –-  w  ten  spo-

Listing 6. Składnia instrukcji warunkowej xsl:choose

<

xsl:choose

>

   

<

xsl:when test=

"wyrażenie1"

>

      

<!-- przypadek pierwszy -->

   

<

/xsl:when

>

   

<

xsl:when test=

"wyrażenie2"

>

      

<!-- przypadek drugi -->

   

<

/xsl:when

>

<

xsl:otherwise

>

      

<!-- przypadek domyślny -->

   

<

/xsl:otherwise

>

<

/xsl:choose

>

Listing 7. Przykład użycia instrukcji warunkowej xsl:choose

<

xsl:choose

>

   

<

xsl:when test=

"age < 18"

>

      

<

td

><

xsl:value-of select=

"age"

/

>

 (niepełnoletni)

      

<

/td

>

   

<

/xsl:when

>

   

<

xsl:when test="age 

>

 60">

      

<

td

><

xsl:value-of select=

"age"

/

>

 (senior)

      

<

/td

>

   

<

/xsl:when

>

<

xsl:otherwise

>

      

<

td

><

xsl:value-of select=

"age"

/

>

      <

/td

>

   

<

/xsl:otherwise

>

<

/xsl:choose

>

Instalacja XSLT w PHP

Aby  móc  korzystać  z  możliwości  języ-
ka  XSLT  w  PHP,  musimy  mieć  zainstalowa-
ną  bibliotekę 

libxslt

  (http://xmlsoft.org/

XSLT/)  oraz  PHP5  uruchomione  z  dyrekty-
wą  – 

with-xsl

.  W  przypadku,  gdy  korzy-

stamy  z  wykupionego  konta  na  serwerze 
wirtualnym, a przykłady zawarte w tym ar-
tykule nie działają poprawnie, musimy po-
prosić  administrację  o  aktywowanie  XSLT. 
Drugim wyjściem jest instalacja serwera na 
własnym komputerze. 

Do  tego  celu  polecamy  XAMPP  –  darmo-
wy  pakiet  zawierający  Apache,  PHP,  My-
SQL,  Perl  
i  inne  oprogramowanie  serwe-
rowe.  XAMPP  jest  bardzo  prosty  w  in-
stalacji  (dostępny  zarówno  na  platfor-
mę  Windows,  jak  i  Linux),  a  jego  aktu-
alna  wersja  standardowo  dostarcza  ob-
sługę  XSLT.  Instrukcje  instalacji  tego  pa-
kietu  (i  inne  informacje)  znajdują  się  na 
stronie  http://www.apachefriends.org/en/
xampp.html
.

background image

01/2008

Narzędzia

58

XSLT

www.phpsolmag.org

59

sób  zidentyfikujemy  m.in.  Firefoksa.  Rów-
nie  dobrze  moglibyśmy  jednak  dokonać  w 
tym  miejscu  odwołania  do  funkcji,  w  któ-
rej sprawdzalibyśmy owy ciąg pod względem 
wielu  fraz  (przechowywanych  np.  w  tabli-
cy)  charakterystycznych  dla  poszczególnych 
przeglądarek.

W  następnym  bloku  kodu  dokonujemy 

sprawdzenia daty ostatniej modyfikacji pli-
ku  users.xml.  Jeśli  owa  modyfikacja  miała 
miejsce  wcześniej  niż  5  minut  temu  (za  tą 
wartość odpowiada liczba 

300 

–jest to ilość 

sekund, jakie dodajemy do daty modyfikacji 
i porównujemy z aktualnym czasem; wszyst-
ko  jest  tutaj  liczone  za  pomocą  unixowego 
znacznika  czasu),  dokonujemy  ponowne-
go generowania pliku XML, a następnie ko-
du  HTML  (tak  jak  w  poprzednim  przykła-
dzie).  Warto  zwrócić  w  tym  miejscu  uwa-
gę na kod:

$xml->appendChild($xml->createProcessingIns

truction(

'xml-stylesheet', 'href="users.xsl" 

type="text/xsl"'

     )
);

znajdujący  się  trochę  powyżej  środkowej 
części pliku. Te dwie linijki dodają do two-
rzonego  dokumentu  XML  odnośnik  wska-
zujący na arkusz XSL – dotychczas nie by-
ło  to  nam  potrzebne,  gdyż  kod  wyjścio-
wy  był  generowany  przez  PHP.  Teraz  gdy 
rozważamy  także  drugą  opcję  (polegająca 
na  dostarczeniu  przeglądarce  kodu  XML 
i  XSL  w  celu  samodzielnego  wygenerowa-
nia  kodu  strony),  potrzebny  jest  nam  od-
powiedni odnośnik (jeśli nie wiesz o jakim 
odnośniku mówimy, spójrz na Listing 1., li-
nijka 2.).

Dalsze  modyfikacje  w  stosunku  do  ko-

du  z  Listingu  6.  zaczynają  się  od  ko-
du 

file_put_contents 

('users.xml', 

$xmlString

),  gdzie  zapisujemy  dane  XML 

do  pliku  users.xml  (lub  aktualizujemy  je-
go zawartość, w przypadku gdy ten plik już 
istnieje). Dalsze instrukcje zależą już od te-
go,  czy  wykryliśmy  obsługę  XSLT  u  użyt-
kownika,  czy  nie.  W  tym  drugim  przypad-
ku  mamy  trochę  więcej  do  zrobienia,  gdyż 
musimy  wygenerować  kod  HTML,  zapisać 
go  do  pliku  oraz  przypisać  go  do  zmiennej 

$result

. W sytuacji, gdy XSLT jest obsługi-

wane,  zamiast  tego  wszystkiego  przypisuje-
my  zmiennej 

$result 

kod  XML.  Wartość 

tej zmiennej zostaje ostatecznie wysłana do 
użytkownika.

Znamy  już  więc  różne  metody  wykorzy-

stania transformacji XSL. Znamy wady i za-
lety każdego rozwiązania. Wiemy już co zro-
bić,  aby  nasz  serwis  wykorzystujący  XSLT 
był  bardziej  wydajny.  Znamy  też  niektóre 
elementy  języka  XSLT.  Aby  jednak  poznać 
jego  podstawy  w  zadowalającej  ilości,  musi-
my jeszcze omówić kilka pominiętych wcze-
śniej aspektów.

Elementy XSLT

Poznaliśmy  już  takie  elementy  jak 

stylesheet

template

for-each 

value-

of

.  Omówimy  jeszcze  2  elementy  (powią-

zane z instrukcjami warunkowymi). Jest ich 
oczywiście dużo więcej, jednak w tym, bądź 
co  bądź,  wprowadzającym  artykule  ogra-
niczymy  się  do  tych  najważniejszych.  Dla 
żądnych  wiedzy  czytelników  dostarczamy 
garść  odnośników  umieszczonych  w  ram-
ce W Sieci.

xsl:if

xsl:if –

 jest to instrukcja warunkowa pełnią-

ca tą samą rolę co

 

if znane z innych języków 

funkcyjnych. Prototyp tej instrukcji prezentuje 
się następująco:

<xsl:if test="wyrażenie">

 

<!-- zawartość 

-->

 

</xsl:if>

gdzie 

wyrażenie

  to  warunek,  który  ma  być 

spełniony.  Przykład  odnoszący  się  do  naszego 
kodu XML mógłby wyglądać następująco:

<xsl:if test="age &lt; 18">
   <td><xsl:value-of select="age"/> 

(niepełnoletni)</td>

</xsl:if>

Efektem  powyższej  instrukcji  będzie  słów-
ko  niepełnoletni  umieszczone  przy  użytkow-
nikach  niemających  18  lat.  Ciąg 

&lt

;  znaczy 

oczywiście  mniejszy  niż  i  jest  równoważne  ze 
znakiem "<" (tego ostatniego jednak z oczywi-
stych powodów nie możemy używać w doku-
mentach XML).

xsl:choose

xsl:choose

 – to kolejna instrukcja warunko-

wa, ta jednak jest podobna do 

switch

 z PHP. 

Można  (a  nawet  trzeba)  jej  używać  z  eleme-
tami 

xsl:when

  oraz 

xsl:otherwise

,  działają-

cymi jak (odpowiednio) 

case

 i 

default

 w in-

strukcji 

switch

.  Składnię  tego  elementu  pre-

zentuje  Listing  6. 

Element  xsl

:otherwise 

jest  nieobowiązkowy,  a  ilość 

xsl:when

  do-

wolna (musi być oczywiście przynajmniej je-
den  taki  element).  Rozbudujmy  trochę  po-
przedni  przykład  sprawdzający  wiek  użyt-
kownika, aby utrwalić zasadę działania tej in-
strukcji  warunkowej.  Przykład  użycia 

xsl:

switch 

prezentuje  Listing  7.  Jeśli  urucho-

mimy ten przykład zauważymy, że druga in-
strukcja  (sprawdzająca,  czy  użytkownik  ma 
więcej niż 60 lat) nigdy się nie wykona. Jest to 
absolutnie prawidłowe. Co więcej, gdybyśmy 
nie mieli instrukcji

 xsl:otherwise

, a żadna z 

xsl:when

 nie zostałaby spełniona, kod po pro-

stu nie zostałby wykonany, a my nie uzyskali-
byśmy żadnego efektu.

Podsumowanie

Transformacje XSL kryją w sobie duże możli-
wości. Wiele aspektów omówiliśmy już w tym 
artykule, jednak równie dużo pozostaje jesz-
cze  do  odkrycia.  Celem  artykułu  było  wpro-
wadzenie czytelnika w świat XSLT, zapozna-
nie go z metodami jego stosowania, omówie-
nie zalet i wad, a przede wszystkim zachęce-
nie  do  dalszej  nauki.  Czytelnicy  zaintereso-
wani  tym  tematem  znajdą  dodatkowe  infor-
macje  w  ramce  W  Sieci.  Najlepszą  metodą 
nauki  jest  eksperymentowanie,  dlatego  gorą-
co  zachęcamy  do  własnoręcznej  modyfikacji 
przykładów.

KAROL GUSAK

Autor  jest  studentem  Informatyki  na  Politechni-
ce  Białostockiej.  Od  kilku  lat  tworzy  hobbystycz-
nie strony internetowe w PHP, a od pewnego czasu 
również aplikacje w C++.
Kontakt z autorem: groadin@gmail.com

W Sieci

•   http://www.zvon.org/xxl/XSLTutorial/Output_pol/contents.html#id1    Bardzo  dobry 

kurs (ang tutorial) XSLT, w całości po polsku; 

•   http://developer.mozilla.org/pl/docs/XSLT  –  Kompendium  wiedzy  o  XSLT,  szczególnie 

warta polecenia jest polska dokumentacja elementów XSLT;

•   http://zvon.org/xxl/XSL-Ref/Tutorials/index.html – Obszerny kurs XSLT, po angielsku; 
•   http://www.w3schools.com/xpath/xpath_intro.asp  –  Bardzo  jasno  napisany  kurs  języka 

XPath, po angielsku; 

•   http://developer.mozilla.org/pl/docs/XPath – Polska dokumentacja osi i funkcji Xpath; 
•   http://webcity.pl/webcity/simplexml_nadchodzi  –  Interesujący  artykuł  przedstawiający 

podstawy użytkowania SimpleXML, po polsku; 

•   http://www.php.net/simplexml  –  Oficjalny  opis  modułu  SimpleXML,  w  języku  angiel-

skim; 

•   http://developer.mozilla.org/pl/docs/DOM – Centrum informacji na temat ogólnie poję-

tego DOM, po polsku; 

•   http://www.php.net/dom/  –  Dokumentacja  modułu  PHP  DOM  wraz  z  przykładami  wy-

korzystania, po angielsku; 

•   http://www.w3schools.com/schema/schema_intro.asp  –  Kurs  XML  Schema  Definition 

(XSD), w języku angielskim.