Język XSL (który sam jest aplikacją XML) pozwala przekształcać dane XML na podstawie czegoś w rodzaju szablonu. Korzystając z tego narzędzia możesz dane przegrupowywać i wybierać. Możesz je także przygotować do wizualnego przeglądania. Na standard XSL składa się język samych przekształceń (XSLT) i język opisu graficznego. Ponieważ opis graficzny XSL nie jest przez żadną z powszechnie używanych przeglądarek internetowych obsługiwany, do prezentacji danych używa się HTML'a, lub XHTML'a. Cała rzecz opiera się na automatycznym poumieszczaniu danych pobranych z dokumentu XML, w wynikowym pliku HTML.
Taki plik HTML służy do prezentacji wybranych w trakcie przekształceń XSLT danych. Ta technika nadaje się wyśmienicie do prezentowania danych w Internecie. Z jednej strony umożliwiamy programom pobranie samych danych, z drugiej serwujemy czytelnikowi ładnie graficznie przygotowane dane. Co więcej, dane te można także zmusić do interakcji z użytkownikiem. Cały czas możemy przecież mieć do nich dostęp. Arkusze stylów XSL mogą być osobnymi plikami, które za pomocą odpowiedniej deklaracji w prologu przypisuje się dokumentom z danymi. Oczywiście jednego arkusza stylów można używać do przekształceń wielu plików z danymi tworzącymi tę samą strukturę. Tak naprawdę, korzystając z tego, że arkusze stylów są "zorientowane" na elementy i inne "węzły" dokumentu XML, można wybiórczo przekształcać poszczególne "węzły" z danymi. Oczywiście najczęściej jest nim po prostu korzeń dokumentu. "Ważne jest, aby korzeń nie został pomylony z głównym elementem. Korzeń zawiera cały dokument. Nie tylko element główny, ale także prolog. W hierarchii znajduje się więc najwyżej." Oto, jak powinna wyglądać deklaracja dołączająca arkusz XSL. Umieszczana oczywiście w prologu dokumentu z danymi:
<?xml-stylesheet type="text/xsl" href="/default.xsl" version="1.0"?>
Gdzie "default.xsl" jest nazwą pliku z arkuszem XSL. To jest najprostszy sposób powiązania XML z XSL. Jeśli otworzymy plik XML z taką deklaracją i oczywiście danymi, to przeglądarka wczyta arkusz stylów, przetworzy dane a efekty wyświetli tak samo, jak wyświetla pliki HTML.
Dla przypomnienia:
Przedstawiany wcześniej niesformatowany plik XML
Sformatowany plik XML za pomocą XSL
Struktura arkusza XSL:
Główny element każdego arkusza XSL to "xsl:stylesheet". Jego podstawowym, wymaganym w zależności od parsera atrybutem jest "version" - aktualnie "1.0". Ma on także atrybut xmlns:xsl, który odpowiada za lokalizację dokumentu z przestrzenią nazw dla XSLT. Arkusz XSL musi zawierać reguły, które będą pasowały do węzłów elementu źródłowego. Musimy zawsze pamiętać, że dokument źródłowy jest traktowany jako drzewo elementów, atrybutów i innych węzłów. Ale skupmy się na samym arkuszu. Wewnątrz jego głównego elementu "xsl:stylesheet" mogą znajdować się podelementy - sekcje "xsl:template". Wybierają one określone przez atrybut "match" węzły przetwarzanego dokumentu źródłowego. Z wyselekcjonowanych w ten sposób węzłów już można pobrać (i wstawić do wyniku) dane, można je także skierować do dalszego przetwarzania, poprzez umieszczenie dyrektywy "xsl:apply-templates". Po jej spotkaniu parser zatrzyma obsługę bieżącej sekcji "xsl:template" i zacznie szukać nowej, odpowiadającej węzłom-dzieciom bieżącego taga. Kiedy wsztkie węzły-dzieci już przetworzy, to wróci do pierwotnej sekcji "xsl:template". Oczywiście węzły-dzieci mogą zawierać własne węzły-dzieci, które również mają własne sekcje "xsl:template". Oto przykładowy, bardzo prosty kod:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
Jeśli w sekcji "xsl:template" nie zastosujemy polecenia "xsl:apply-templates", to żadne nie przekształcone dotychczas podelementy bieżącego elementu nie zostaną przekształcone, nawet jeśli są odpowiadające im inne sekcje "xsl:template"." Ten dokument zawiera dokładnie jedną sekcję "xsl:template". Wartością jej parametru "match" jest "/", co oznacza korzeń dokumentu (tak, korzeń też jest węzłem). Oczywiście procesor XSL zawsze przejdzie do takiej sekcji "xsl:stylesheet" i to na samym początku przetwarzania każdego dokumentu XML. Jest tak dlatego, że w strukturze dokumentu XML zawsze najwyżej znajduje się korzeń. Jak widać, wprawdzie w tej sekcji "xsl:template" jest instrukcja "xsl:apply-templates", ale mogło by jej tam w ogóle nie być. Dlaczego? Procesor i tak nie znajdzie innych sekcji "xsl:template", bo ich po prostu nie ma. Jeśli użyjemy takiego prostego arkusza stylów, to wynikem przekształceń absolutnie każdego poprawnie sformatowanego dokumentu XML będzie:
<listing>
</listing>
Jak widać, tagi nie poprzedzone prefiksem "xsl:", zostaną po prostu umieszczone w dokumencie wynikowym. Spróbujmy teraz przeprowadzić transformację konkretnego dokumentu:
<listing>
<dokument tytuł="Instrukcja obsługi klawiatury">
<par>
W tym rozdziale dowiemy się jak używać klawiatury.
</par>
<par>
Myślę, że warto to przeczytać.
</par>
</dokument>
</listing>
Występują w nim następujące węzły: korzeń, element "dokument", jego parametr "tytuł" oraz dwa elementy "par". Wszystkie interesujące nas dane należą do elementu "dokument", więc to on będzie pierwszym celem instrukcji "xsl:template":
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/199/XSL/Transform">
<xsl:template match="dokument">
<xsl:apply-templates>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
W atrybucie "match" znajduje się nazwa szukanego elementu "dokument". Po jego odnalezieniu do wyniku zostanie wstawione trochę kodu HTML (dwa otwierające znaczniki), następnie procesor XSL wykona instrukcję "xsl:apply-templates", czyli będzie próbował przetwarzać elementy potomne i na koniec ponownie wstawi trochę kodu HTML (tym razem dwa zamykające znaczniki). Teraz zajmiemy się "wyciągnięciem" z dokumentu wszelkich możliwych danych. Za pobieranie rozmaitych wartości odpowiada instrukcja "xsl:value-of", która posiada jeden parametr - "select". Określa on, co ma zostać pobrane. Bieżący węzeł oznacza tutaj ".".
Oto uzupełniony arkusz XSL.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/199/XSL/Transform">
<xsl:template match="dokument">
<h1><xsl:value-of select="@tytuł"></xsl:value-of></h1>
<xsl:apply-templates>
<xsl:template match="par">
<p><xsl:value-of select=".">
</xsl:value-of></p>
</xsl:template>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
Oczywiście po odczytaniu polecenia "xsl:apply-templates", procesor XSL przejdzie do pierwszej odpowiadającej elementowi "par" (bo to kolejny element w dokumencie źródłowym) sekcji "xsl:template" (tutaj: druga sekcja tego typu). Tyle wystarczy, jeśli przekształcamy dokument za pomocą jednego z zewnętrznych, zgodnych ze specyfikacją parserów. Jeśli zaś korzystamy z przekształceń "w locie" Internet Explorera 5 i być może jeszcze innych, bardziej wymagających procesorów, to zawsze musimy uwzględnić korzeń dokumentu. Więc aby arkusz działał także z tą przeglądarką, powinniśmy dodać na samym jego początku sekcję "xsl:template" z atrybutem "match" równym "/", która zawiera instrukcję "xsl:apply-templates". Oto ostateczny, bardziej uniwersalny arkusz:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/199/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates>
</xsl:apply-templates>
<xsl:template match="dokument">
<h1><xsl:value-of select="@tytuł"></xsl:value-of></h1>
<xsl:template match="par">
<p><xsl:value-of select="."></xsl:value-of></p>
</xsl:template>
</xsl:apply-templates>
</xsl:template>
</xsl:template>
</xsl:stylesheet>
Jeśli chcemy po kolei przekształcać wszystkie elementy spełniające dany warunek, możemy użyć polecenia "xsl:for-each". Posiada ono atrybut "select", który określa, co ma zostać przekształcone. Dla przykładu:
<xsl:template match="dokument">
<xsl:for-each select="par">
<p><xsl:value-of select="."></xsl:value-of></p>
</xsl:for-each>
</xsl:template>
Kod z wydruku powyżej pobierze po kolei wszystkie zawartości znajdujących się wewnątrz elementu "dokument" elementów "par" i umieści je między znacznikami "p". Podczas wyboru węzłów do przekształceń dostępne są wieloznaczniki. Pozwalają one tworzyć reguły domyślne, których stosowanie daje gwarancję, że żaden element z dokumentu źródłowego nie zostanie pominięty. Bez znaczenia, jakie on zajmuje miejsce w strukturze. Podstawowym symbolem wieloznacznym jest "*". Można go oczywiście użyć w atrybucie "match" sekcji "xsl:template". Jeśli chcemy aby reguła działała także dla korzenia, możemy użyć symbolu "/":