Extensible Stylesheet Language to sposób prezentacji dokumentów XML oparty o transformacje dokumentów. Arkusz określa sposób zamiany dokumentu XML na inny dokument XML, dla którego określony jest już sposób prezentacji. Zgodnie z ideą standardu XSL, dokumentem wyjściowym powinien być dokument XSL Formatting Objects, ale w praktyce najczęściej dokonuje się transformacji do XHTML.
XSL Transformations to język (zastosowanie XML) służący do pisania arkuszy dokonujących transformacji XML → XML. Procesor XSLT to aplikacja, która potrafi interpretować XSLT i mając dane wejściowy dokument XML oraz arkusz XSLT potrafi wygenerować wynikowy dokument XML.
Arkusz (stylesheet) składa się z szablonów (templates). Każdy szablon opisuje jak zamieniać pewien fragment dokumentu wejściowego na fragment dokumentu wyjściowego. Wykonanie transformacji polega na wywołaniu szablonu pasującego do elementu głównego.
Zastosowania XSLT są znacznie szersze niż wizualizacja XML. Jest to doskonałe narzędzie do przepisywania dokumentów XML z jednego formatu do innego, do wyciągania danych z dokumentów, do przepisywania dokumentów do innych niż XML formatów. Wiele funkcjonalności pokrywa się z XQuery.
XSLT 2.0 zdefiniowany jest w rekomendacji:
Inne standardy i dokumenty związane z XSLT:
Wersja 1.0:
Podczas ćwiczeń w labie najwygodniej korzystać z XML Spy.
Należy napisać lub otworzyć arkusz XSLT, a następnie wcisnąć przycisk "XSL". Aplikacja poprosi o wskazanie dokumentu źródłowego. Alternatywnie można wykonać przekształcenie dla otwartego dokumentu i wskazać arkusz.
Saxon to procesor XSLT i XQuery dla Javy i .NET. Obsługuje standardy XPath 2.0, XSLT 2.0, XQuery 1.0. Udostępnia zarówno prosty interfejs command-line, jaki i API (dla Javy zgodne z JAXP 1.3), dzięki któremu z procesorów można korzystać we własnych programach.
Oprogramowanie w podstawowej wersji jest darmowe (open-source). Wersja zaawansowana (ze wsparciem dla przetwarzania schema aware) jest komercyjna.
W ścieżce klas powinien występować plik saxon9.jar. Przykłady użycia interfejsu command-line:
-cp
.Wartosc
.
Jeśli napis zawiera spacje lub podejrzane znaki, najlepiej ująć go w apostrofy.Xsltproc to procesor XSLT napisany w C, oparty o bibliotekę Libxml. Na ogół jest dostępne w dystrybucjach Linuksa. Obsługiwany jest standard XSLT 1.0.
Xalan to bardzo popularny procesor XSLT napisany w Javie. Obecnie obsługuje XSLT 1.0.
Przeglądarki internetowe rozpoznają instrukcję przetwarzania xml-stylesheet
w dokumencie źródłowym
i wykonują wskazane przekształcenie, a następnie wyświetlają wynik.
<!-- element główny: --> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- konfiguracja arkusza, globalne deklaracje: --> <xsl:output method="html" encoding="iso-8859-2" /> <xsl:import href="inny_arkusz.xsl"/> <xsl:param name="css"/> <!-- szablony: --> <xsl:template match="/"> <html> <head><link rel="styesheet" type="text/css" href="{$css}"/></head> <body><xsl:apply-templates/></body> </html> </xsl:template> <xsl:template match="akapit"> <p><xsl:value-of select="."/></p> </xsl:template> </xsl:stylesheet>
Arkusz (stylesheet) składa się z szablonów (templates). Każdy szablon opisuje jak zamieniać pewien fragment dokumentu wejściowego na fragment dokumentu wyjściowego. Wykonanie transformacji polega na wywołaniu szablonu pasującego do elementu głównego.
Poza szablonami arkusz może zawierać elementy takie jak (między innymi):
output
– określa sposób serializacji dokumentu,include
– zaimportowanie innego arkusza („wklejenie” w miejscu odwołania),import
– zaimportowanie szablonów z innego arkusza z niższym priorytetem, musi występować na początku arkusza,param
, variable
– globalne parametry i zmienne.Treść szablonu jest wyrażeniem opisującym zawartość dokumentu wynikowego. Nie ma tutaj imperatywnych poleceń modyfikujących stan, wypisujących coś na wyjście itd., dlatego XSLT można uznać za język deklaratywny.
Wynikiem transformacji jest dokument XML. Standard określa trzy sposoby serializacji (zapisania jako tekstu) wynikowych dokumentów:
Instrukcja <apply-templates select="ścieżka"/>
powoduje:
apply-templates
znajdują się elementy sort
,dla każdego węzła z sekwencji:
Istnieje także instrukcja <call-template name="nazwa"/>
,
pozwalająca na wywołanie szablonów nazwanych. W tym przypadku węzeł bieżący się nie zmienia.
Atrybut match
w elemencie template
mówi do jakich węzłów dany szablon będzie aplikowany.
Jego wartością powinien być wzorzec – ograniczona wersja ścieżki XPath. Ten sam węzeł może pasować do wielu szablonów
i ich pól match
. Wówczas intuicyjnie wybierany jest ten szablon, który najbardziej precyzyjnie określa
dany węzeł, a w przypadku konfliktu decyduje kolejność deklaracji – dokładnie opisuje to rekomendacja.
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/studenci"> <html> <body><table> <xsl:apply-templates select="student"> <xsl:sort select="naz" data-type="text" lang="pl"/> </xsl:apply-templates> </table></body> </html> </xsl:template> <xsl:template match="student"> <tr> <td><xsl:value-of select="naz"/></td> <td><xsl:value-of select="imi"/></td> <td><xsl:value-of select="gr"/></td> </tr> </xsl:template> </xsl:stylesheet>
Tryby przetwarzania (modes) pozwalają na przetwarzanie tego samego
węzła na wiele różnych sposobów. Podczas przetwarzania zawsze obowiązuje jeden tryb bieżący,
który może się zmieniać przy wywołaniach apply-templates
. W wywołaniu mówimy, jaki tryb
ma zostać użyty. W szablonach mówimy, w jakich trybach dany szablon ma być używany.
Szablon może posiadać atrybut mode
, w którym określa się
w jakich trybach szablon ma być używany. Wartością atrybutu jest lista rozdzielonych spacjami tokenów, którymi mogą być:
#default
– oznacza tryb domyślny,#all
– oznacza, że szablon działa we wszystkich trybach.
Instrukcja apply-templates
może posiadać atrybut mode
,
którego wartością jest jeden token:
#default
– oznacza tryb domyślny,#current
– oznacza, że stosujemy tryb bieżący.Podczas dopasowywania szablonów używane są tylko szablony właściwe dla wskazanego trybu.
Istnieje jeden tryb domyślny, który nie posiada nazwy,
i jest trybem aktywnym na początku przetwarzania. Szablon bez atrybutu mode
działa (tylko) w trybie domyślnym, a instrukcja apply-templates
bez atrybutu
mode
uruchamia przetwarzanie w trybie domyślnym. Tryb domyślny jest także
uruchamiany zawsze podczas przetwarzania ciała funkcji (ale nie jest tak już dla ciała
zmiennych, parametrów ani szablonów nazwanych – w tych przypadkach po prostu dalej obowiązuje tryb bieżący).
Kiedy obliczany jest szablon dla danego węzła, ten węzeł staje się węzłem bieżącym.
Instrukcje, które zmieniają węzeł bieżący to: apply-templates
i for-each
.
W wyrażeniach XPath można się do niego odwołać za pomocą funkcji current()
,
w każdym miejscu w ścieżce XPath current()
ma tą samą wartość.
Węzeł kontekstowy na samym początku obliczania wyrażenia XPath jest równy węzłowi bieżącemu,
a dalej w miarę przechodzenia kolejnych kroków ścieżki XPath zmienia się.
W każdym miejscu można się do niego odwołać za pomocą kropki .
(lub wyrażenia self::node()
).
Przykład:
//section[position() = current()/@numer]
– wszystkie elementy section
,
o pozycji równej atrybutowi numer
węzła bieżącego;
//section[position() = @numer]
– wszystkie elementy section
,
o pozycji równej swojemu atrybutowi numer
;
Do tworzenia poszczególnych węzłów dokumentu wynikowego służą odpowiednie elementy szablonu:
<xsl:element name="elem"> <xsl:attribute name="atryb">wartość atrybutu</xsl:attribute> <xsl:text>Zawartość tekstowa</xsl:text> </xsl:element> <xsl:comment>To będzie komentarz</xsl:comment> <xsl:processing-instruction target="xml-stylesheet">type="text/css" href="styl.css"</xsl:processing-instruction>
Można też po prostu wpisywać fragmenty wynikowego dokumentu jako XML (ale nie wszystko da się tak wyrazić).
<elem atryb="wartość atrybutu"> Zawartość tekstowa </elem> <xsl:comment>To będzie komentarz</xsl:comment> <xsl:processing-instruction target="xml-stylesheet">type="text/css" href="styl.css"</xsl:processing-instruction>
Aby utworzyć węzeł taki sam jak węzeł bieżący, można użyć instrukcji copy
.
Domyślnie kopiowanie jest powierzchowne, aby skopiować również atrybuty i podelementy trzeba to zrobić "ręcznie" wewnątrz copy
.
Węzłem bieżącym może być nie tylko element, ale też np. atrybut, węzeł tekstowy.
<xsl:template match="*|@*" <xsl:copy> <xsl:apply-templates select="child::node() | attribute::node()"/> </xsl:copy> </xsl:template>
XSLT dostarcza konstrukcji do pisania wyrażeń warukowych (if
, choose
)
oraz iterowania po elementach sekwencji (for-each
).
Wewnątrz for-each
zmienia się węzeł bieżący. Jeśli pierwszymi podelementami for-each
będą
sort
, elementy sekwencji zostaną posortowane.
<xsl:if test="$x < 1">x jest mniejsze od 1</xsl:if> <xsl:if test="tytuł"> <h2><xsl:value-of select="tytuł"/></h2> </xsl:if> <xsl:choose> <xsl:when test="$x = 1">x równe 1</xsl:when> <xsl:when test="$x = 2">x równe 2</xsl:when> <xsl:otherwise>x różne od 1 i 2</xsl:otherwise> </xsl:choose> <xsl:for-each select="row[position() >= 2]">kolejny wiersz</xsl:for-each>
Aby wstawić do dokumentu wynikowego wartość wyrażenia XPath, można użyć instrukcji value-of
(rzutuje wynik na tekst)
lub copy-of
(wstawia z poddrzewem), a w XSLT 2.0 także sequence
.
copy-of
różni się od sequence
tym, że węzły w wyniku są tu kopiami węzłów
z wyrażenia w select
, tzn. nie są z nimi identyczne w sensie is
(dotyczy to także całego poddrzewa).
Dla odróżnienia w sequence
wstawiane są te same węzły.
Niektóre atrybuty elementów XSLT oczekują wartości będących wyrażeniami XPath.
Są to np. select
, test
. W pozostałych atrybutach można wstawić wartość tekstową wyrażenia XPath
pisząc (podobnie jak w XQuery) {wyrażenie}
.
<xsl:for-each select="./tekst"> <p class="{@styl}"><xsl:value-of select="."/></p> </xsl:for-each> <xsl:template match="fragment_html"> <xsl:copy-of select="node()"/> </xsl:template>
apply-templates
.
Struktura wynikowa nie jest jednoznacznie ustalona. Nadaje się do przetwarzania dokumentów o nieustalonej strukturze,
modelu mieszanego, elementów zagnieżdżonych rekurencyjnie. Prosty przykład: studenci1.xsl.for-each
.
Dobry gdy wynik musi mieć ściśle określoną strukturę. Prosty przykład: studenci2.xsl.Często miesza się oba style. Np. dla wyniku HTML stylem „wynikowym” tworzy się nagłówki i elementy o ściśle określonej strukturze (tabele, formularze), a gdy dokument wejściowy zawiera gdzieś model mieszany, stylem „wejściowym” tworzy się zawartość tekstową z możliwymi zanurzonymi elementami formatującymi.
Przykład studenci: studenci.xml, studenci1.xsl, studenci2.xsl.
Niech arkusz wybiera tylko studentów z pierwszej grupy.
Wyświetlaj kursywą (<i>
) nazwiska studentów, których status jest równy prosba
.
Wprowadź parametr określający numer grupy, z której studentów ma wybierać arkusz. Jeśli nie zostanie podany, mają być wybierani wszyscy.
Utwórz nowy arkusz tworzący plik XML o takiej samej strukturze, ale wybierający tylko studentów z danej grupy (parametr) i sortujący ich według nazwisk.
sklep1.xml – napisz arkusz, który wypisuje kolejno wszystkie kategorie i dla każdej kategorii wszystkie towary z tej kategorii.
To samo dla pliku sklep2.xml.