XML – eXtensible Markup Language
część 8
XSL transformations (XSLT)
XSLT (ang. eXtensible Stylesheet Language Transformations) jest
opartym na XML językiem transformacji dokumentów XML
XSLT umożliwia „przetłumaczenie” dokumentów z jednego formatu
XML na inny format XML, ale również na HTML, PDF i inne.
dokument XML
arkusz XSLT
plik wyjściowy
(XML, HTML, PDF etc.)
procesor XSLT
Arkusze XSLT określają w jaki sposób przekształcić poszczególne
elementy wejściowe pliku XML.
Przykład
<xsl:attribute>
Do elementu HTML możemy dodać atrybut będący zawartością jakiegoś elementu bądź wartością atrybutu z dokumentu XML.
<body>
<h3>Obrazki</h3>
<xsl:for-each select="galeria/obrazek">
<img>
<xsl:attribute name="src">
<xsl:value-of select="."/>
</xsl:attribute>
</img>
</xsl:for-each>
</body>
<galeria>
<obrazek>most.jpg</obrazek>
<obrazek>widok.jpg</obrazek>
</galeria>
Przykład
<xsl:attribute>
<galeria>
<obrazek plik="most.jpg"/>
<obrazek plik="widok.jpg"/>
</galeria>
<body>
<h3>Obrazki</h3>
<xsl:for-each select="galeria/obrazek">
<img>
<xsl:attribute name="src">
<xsl:value-of select="@plik"/>
</xsl:attribute>
</img>
</xsl:for-each>
</body>
Inaczej:
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="application/xml" href="arkusz.xsl"?> <spis_osob> <osoba> <imie>Marek</imie> <nazwisko>Nowak</nazwisko> <wiek>23</wiek> </osoba> <osoba> <imie>Tomasz</imie> <nazwisko>Pawlak</nazwisko> <wiek>33</wiek> </osoba> <osoba> <imie>Piotr</imie> <nazwisko>Kaczkowski</nazwisko> </osoba> </spis_osob>
Przykład
Element nie istnieje?
<table border="1"> <tr> <th>First name</th><th>Last name</th><th>Age</th> </tr> <xsl:for-each select="spis_osob/osoba"> <tr> <td><xsl:value-of select="imie"/></td> <td><xsl:value-of select="nazwisko"/></td> <xsl:choose> <xsl:when test="wiek"> <td><xsl:value-of select="wiek"/></td> </xsl:when> <xsl:otherwise> <td style="background-color:red"> <xsl:text>brak danych</xsl:text> </td> </xsl:otherwise> </xsl:choose> </tr> </xsl:for-each> </table>
Przykład (cd)
Element nie istnieje?
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="osoba">
abc
</xsl:template>
</xsl:stylesheet>
Przykład
W przeglądarce:
Odwołanie do elementów o określonej nazwie.
<xsl:template>
<xsl:call-template name="templatename">
<!-- Content:xsl:with-param* -->
</xsl:call-template>
Składnia:
Instrukcja ta pozwala nam wywołać szablon o określonej nazwie.
<xsl:call-template>
Przykład (cd)
<xsl:attribute>
Arkusz XSL:
<xsl:template match="/">
<html>
<body>
<h3>Obrazki</h3>
<xsl:for-each select="galeria/obrazek">
<xsl:call-template name="test"/>
</xsl:for-each>
</body>
</html>
</xsl:template>
<xsl:template name="test">
abc
</xsl:template>
<galeria>
<obrazek plik="most.jpg"/>
<obrazek plik="widok.jpg"/>
</galeria>
Dokument XML:
Przykład (cd)
<xsl:attribute>
Czy można do szablonu przekazać zawartość elementu ew. wartość atrybutu?
<xsl:template match="/">
<html>
<body>
<h3>Obrazki</h3>
<xsl:for-each select="galeria/obrazek">
<xsl:call-template name="test"/>
</xsl:for-each>
</body>
</html>
</xsl:template>
<xsl:template name="test">
abc
</xsl:template>
?
<xsl:param name="name" select="expression">
<!-- Content:template -->
</xsl:param>
Składnia:
Deklaracja lokalnego bądź globalnego parametru.
<xsl:param>
Parametr jest lokalny jeżeli jest zadeklarowany w elemencie template.
Atrybuty: • name – określa nazwę parametru (wymagany)
• select – wartość w postaci wyrażenia XPath
(opcjonalny)
<xsl:with-param name="name" select="expression">
<!-- Content:template -->
</xsl:with-param>
Składnia:
Definiujemy wartość parametru, który ma być przekazany do szablonu.
<xsl:with-param>
Atrybuty: • name – określa nazwę parametru (wymagany)
• select – wartość w postaci wyrażenia XPath
(opcjonalny)
<xsl:param> + <xsl:with-param>
Jeżeli szablon wymaga parametru:
<xsl:template name="tname">
<xsl:param name="pname"/>
...
$pname
...
</xsl:template>
…to musimy do „przesłać” do szablonu przy wywołaniu:
<xsl:call-template name="tname">
<xsl:with-param name="pname" select="expression"/>
</xsl:call-template>
<xsl:param> + <xsl:with-param>
Przykład
<body>
<h3>Obrazki</h3>
<xsl:for-each select="galeria/obrazek">
<xsl:call-template name="test">
<xsl:with-param name="plik" select="." />
</xsl:call-template>
</xsl:for-each>
</body>
<xsl:template name="test">
<xsl:param name="plik"/>
<img>
<xsl:attribute name="src">
<xsl:value-of select="$plik"/>
</xsl:attribute>
</img>
</xsl:template>
<galeria>
<obrazek plik="most.jpg"/>
<obrazek plik="widok.jpg"/>
</galeria>
<xsl:variable name="name" select="expression">
<!-- Content:template -->
</xsl:variable>
Składnia:
Deklaracja lokalnej bądź globalnej zmiennej.
<xsl:variable>
Zmienna jest loklana jeżeli jest zadeklarowana w elemencie template.
UWAGA: raz ustalona zmienna nie powinna zmieniać wartości!!!
<xsl:variable name="osoba" select="'Przemek'"/>
<xsl:template match="/">
<html><body>
<h3>Spis</h3>
<xsl:copy-of select="$osoba" />
</body></html>
</xsl:template>
Przykład
W przeglądarce:
Nadanie wartości zmiennej przez atrybut.
<xsl:variable>
<xsl:variable name="osoba">
<osoba>
<imie>Przemek</imie>
<nazwisko>Kowal</nazwisko>
<wiek>42</wiek>
</osoba>
</xsl:variable>
<xsl:template match="/">
<html><body>
<h3>Spis</h3>
<xsl:copy-of select="$osoba"/>
</body></html>
</xsl:template>
Przykład
Nadanie wartości zmiennej przez zawartość elementu.
<xsl:variable>
W przeglądarce:
<xsl:variable name="osoba" select="'Przemek'"/>
<xsl:template match="/">
<html><body>
<h3>Spis</h3>
<xsl:copy-of select="$osoba" />
</body>
</html>
</xsl:template>
<xsl:variable name="osoba" select="'Agata'"/>
Przykład
A co jeżeli zmienimy wartość zmiennej?
<xsl:variable>
W przeglądarce:
Przykład
Nadanie wartości zmiennej przez wyrażenie XPath.
<xsl:variable>
<liczby start="1" stop="31"/>
Arkusz XSL:
Dokument XML:
<xsl:variable name="a" select="/liczby/@start"/>
<xsl:variable name="b" select="/liczby/@stop"/>
<xsl:template match="/">
<html>
<body>
<p>a=<xsl:value-of select="$a"/></p>
<p>b=<xsl:value-of select="$b"/></p>
</body>
</html>
</xsl:template>
<xsl:variable name="start" select="/tabela/@start"/>
<xsl:variable name="stop" select="/tabela/@stop"/>
<xsl:variable name="zm1" select="$start + $stop"/>
<xsl:variable name="zm2" select="$start + $stop + 10"/>
<xsl:template match="/">
<html>
<body>
<p>zmienna 1 = <xsl:value-of select="$zm1"/></p>
<p>zmienna 2 = <xsl:value-of select="$zm2"/></p>
</body>
</html>
</xsl:template>
Przykład
<xsl:variable>
W przeglądarce:
Przykład
Rozważmy teraz następujący program:
<xsl:variable>
int start=1;
int stop=10;
int main()
{
for(int i=start;i<=stop;i++)
{
cout<<i;
}
return 0;
}
Przykład
Rozważmy teraz następujący program:
<xsl:variable>
int start=1;
int stop=10;
void wypisz(int i)
{
if(i<stop+1)
{
cout<<i;
wypisz(++i);
}
}
int main()
{
wypisz(start);
return 0;
}
<?xml version="1.0"?>
<?xml-stylesheet type="application/xml"
href="arkusz.xsl"?>
<liczby start="1" stop="10"/>
Przykład
Nadanie wartości zmiennej przez wyrażenie XPath.
<xsl:variable>
Dokument XML:
Arkusz XSL:
<xsl:variable name="start" select="/liczby/@start"/>
<xsl:variable name="stop" select="/liczby/@stop"/>
<liczby start="1" stop="10"/>
Przykład (cd)
<xsl:variable>
Arkusz XSL (cd):
<xsl:template name="liczby">
<xsl:param name="index" select="$start"/>
<xsl:if test="$index < $stop+1">
<span><xsl:value-of select="$index"/></span>
<xsl:call-template name="liczby">
<xsl:with-param name="index" select="$index+1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<liczby start="1" stop="10"/>
Przykład (cd)
<xsl:variable>
Arkusz XSL (cd):
<xsl:template match="/">
<html>
<body>
<h3>Wypisujemy liczby</h3>
<xsl:call-template name="liczby"/>
</body>
</html>
</xsl:template>
W przeglądarce:
Przykład (już omawiany ale zmodyfikowany!)
<xsl:text>
<xsl:template name="liczby">
<xsl:param name="index" select="$start"/>
<xsl:if test="$index < $stop+1">
<span><xsl:value-of select="$index"/></span>
<xsl:text>,</xsl:text>
<xsl:call-template name="liczby">
<xsl:with-param name="index" select="$index+1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
Element umożliwiający dodanie tekstu do pliku wynikowego.
Przykład (już omawiany ale zmodyfikowany!)
<xsl:text>
<xsl:template name="liczby">
<xsl:param name="index" select="$start"/>
<xsl:if test="$index < $stop+1">
<span><xsl:value-of select="$index"/></span>
<xsl:if test="$index!=$stop">
<xsl:text>,</xsl:text>
</xsl:if>
<xsl:call-template name="liczby">
<xsl:with-param name="index" select="$index+1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
Przykład (już omawiany ale zmodyfikowany!)
<xsl:text>
<xsl:template name="liczby">
<xsl:param name="index" select="$start"/>
<xsl:if test="$index < $stop+1">
<span><xsl:value-of select="$index"/></span>
<xsl:if test="$index=$stop">
<xsl:text>,</xsl:text>
</xsl:if>
<xsl:call-template name="liczby">
<xsl:with-param name="index" select="$index+1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>