XSLT

References for subject 10

Generation 1.0:

Generation 2.0:

Wprowadzenie

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. Standard XSL przewiduje XSL Formatting Objects jako docelowy fromat przekształceń, ale w praktyce najczęściej dokonuje się transformacji do (X)HTML.

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.

Zastosowania XSLT są znacznie szersze niż prezentacja 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.

Tools

Eclipse

Eclipse (w wersji dla programistów Java EE lub z odpowiednimi dodatkami) pomaga edytować arkusze XSLT, pozwala je także uruchamiać.

Do uruchomienia wystarczy klinkąć w polecenie Run przy aktywnym oknie z arkuszem. Następnie w Run Configurations można skonfigurować sposób uruchamiania.

Eclipse pozwala skorzystać z wbudowanego procesora Javy oraz dostarczonych z zewnątrz Xalana i Saxona (także dla wersji 2.0).

Saxon

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, jak i API (dla Javy zgodne z JAXP), dzięki któremu z procesorów można korzystać we własnych programach.

Oprogramowanie w podstawowej wersji jest otwarte. Wersja zaawansowana (ze wsparciem dla przetwarzania schema aware) jest komercyjna.

W ścieżce klas powinien występować plik saxon9he.jar - zrobimy to za pomocą opcji -cp. Przykłady użycia interfejsu command-line:

  • java -cp sahon9he.jar net.sf.saxon.Transform -xsl:arkusz.xsl -s:plik.xml -o:wynik.html – Wykonanie przekształcenia arkusz.xsl na pliku plik.xml i zpisanie wyniku w wynik.html.
  • java -cp sahon9he.jar net.sf.saxon.Transform -xsl:arkusz.xsl -s:plik.xml -o:wynik.html param=Wartosc inny='Ala ma kota' – Przypisanie parametrowi param wartości napisowej Wartosc. Jeśli napis zawiera spacje lub podejrzane znaki, najlepiej ująć go w apostrofy.
  • java -cp sahon9he.jar net.sf.saxon.Transform -xsl:arkusz.xsl -s:plik.xml -o:wynik.html +param=plik.xml – Przypisanie parametrowi param jako wartości węzła (korzenia) dokumentu odczytanego z pliku plik.xml.
  • java -cp sahon9he.jar net.sf.saxon.Transform -xsl:arkusz.xsl -s:plik.xml -o:wynik.html '?param=//pracownik[5]' – Przypisanie parametrowi param jako wartości wyniku podanego wyrażenia (obliczanego w kontekście dokumentu źródłowego).

Xsltproc

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.

Uruchamianie:

  • xsltproc -o wynik.html arkusz.xsl plik.xml
  • xsltproc -param wartosc=/sciezka/xpath -stringparam 'napis=Ala ma kota' -o wynik.html arkusz.xsl plik.xml

Xalan

Xalan to bardzo popularny procesor XSLT napisany w Javie. Obecnie obsługuje XSLT 1.0.

Przeglądarki internetowe

Przeglądarki internetowe rozpoznają instrukcję przetwarzania xml-stylesheet w dokumencie źródłowym i wykonują wskazane przekształcenie, a następnie wyświetlają wynik.

Task 1.

Take files staff.xml and staff-html.xsl.

Run the tranformation in one of the tools described above.

Arkusz XSLT

Struktura arkusza

Example 1.

<!-- 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:apply-templates /></p>
  </xsl:template>
</xsl:stylesheet>

Arkusz (stylesheet) składa się z szablonów (templates). Każdy szablon opisuje jak zamieniać pewien węzeł 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.

Serializacja

Wynikiem transformacji jest dokument XML. Standard określa cztery sposoby serializacji (zapisania jako tekstu) wynikowych dokumentów:

  • xml – zapisywany jest dokument XML,
  • text – wypisanie tylko węzłów tekstowych dokumentu, bez żadnych znaczników,
  • html – jeśli wynikiem drzewo dokumentu HTML, zostaje on zapisany jako HTML (jest poprawnie interpretowany przez stare przeglądarki),
  • xhtml – dostępny w XSLT 2.0, niemal identyczny z xml.

Task 2.

Run the 'staff' example in different seralisation modes.

Typowe zastosowanie – prezentacja dokumentów tekstowych

Jednym z typowych zastosowań XSLT jest przekształcanie dokumentów tekstowych zawierających znaczniki strukturalne i semantyczne do HTML lub innego formatu służącego prezentacji. W takim zastosowaniu arkusz jest zbudowany z wielu szablonów, zasadniczo po jednym dla każdego typu elementu w dokumencie źródłowym, a sterowanie przekształceniem odbywa się za pomocą instrukcji apply-templates. Mamy wtedy do czynienia z przekształceniem sterowanym strukturą dokumentu źródłowego.

Example 2.

...
<xsl:template match="definicja">
  <div class="definicja">
    <xsl:apply-templates/>
  </div>
</xsl:template>

<xsl:template match="pracownicy">
  <ul>
    <xsl:apply-templates/>
  </ul>
</xsl:template>

<xsl:template match="pracownik">
  <li>
    <xsl:apply-templates/>
  </li>
</xsl:template>
...

Wywoływanie szablonów

Instrukcja <apply-templates select="ścieżka"/> powoduje:

  1. obliczenie wartości ścieżki, wynikiem powinna być sekwencja węzłów; jeśli brakuje atrybutu select, przyjmowane jest child::node() (wszystkie dzieci bieżącego węzła)
  2. posortowanie sekwencji, jeśli wewnątrz apply-templates znajdują się elementy sort,
  3. dla każdego węzła z sekwencji:

    1. dopasowanie szablonu najlepiej pasującego do węzła,
    2. ewaluacja dopasowanego szablonu ze zmienionym węzłem bieżącym,
    3. wstawienie otrzymanego wyniku do wynikowego drzewa.

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.

Task 3.

Make the following enhancements to the staff-html stylesheet:

  1. Present the name of the comany as h1 and the name of department as h2.
  2. Present each phone number in a separate line or paragraph.
  3. Present salary in a separate paragraph and use a distinguishable font or color for it.

Węzeł bieżący i węzeł kontekstowy

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()).

Task 4.

For each person write the number of employees hired on the same position and having greater salary.

Kilka instrukcji XSLT

Sterowanie

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.

Example 3.

<xsl:template match="rozdział">
  <xsl:if test="@tytuł">
    <h2>Tytuł: <xsl:value-of select="@tytuł"/></h2>
  </xsl:if>
  <xsl:apply-templates />
</xsl:template>
<xsl:template match="konto">
Saldo konta jest
  <xsl:choose>
  <xsl:when test="saldo &gt; 0">dodatnie</xsl:when>
  <xsl:when test="saldo &lt; 0">ujemne</xsl:when>
  <xsl:otherwise>równe zero</xsl:otherwise>
  </xsl:choose>.
</xsl:template>
<xsl:template match="pracownicy">
  <table>
    <xsl:for-each select="pracownik">
      <tr>
      	<td><xsl:value-of select="imię"/></td>
      	<td><xsl:value-of select="nazwisko"/></td>
      </tr>
    </xsl:for-each>
  </table>
</xsl:template>

Task 5.

Add a prefix before phone number according to the type of the number: mob. for mobile phone, fax for fax, tel. for office phone.

Task 6.

(temporary) Present only employees from Accountancy department.

Task 7.

Add a global stylesheet parameter dep. If the parameter is provided, present only departments with the given id (and included employees). If the parameter is not provided, present all departments and employees.

Task 8.

(optional, if you have too much time ;)) Add a global stylesheet parameter pos. If the parameter is provided, present only employees of the given position (attribute of each employee). If the parameter is not provided, present all employees. Let the two parameters work together.

Kopiowanie oraz wyrażenia XPath w XSLT

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). 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}.

Example 4.

<xsl:for-each select="student">
  <p id="st{@nr-indeksu}">
    <xsl:value-of select="naz"/> <xsl:value-of select="imi"/>
  </p>
</xsl:for-each>

<xsl:template match="fragment_html">
  <xsl:copy-of select="node()"/>
</xsl:template>

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.

Example 5.

<xsl:template match="*|@*"
<xsl:copy> <xsl:apply-templates select="child::node() | attribute::node()"/> </xsl:copy>
</xsl:template>

Task 9.

Check whether the copy instruction copies the value of a text node or attribute.

Instrukcje do tworzenia węzłów

Do tworzenia poszczególnych węzłów dokumentu wynikowego można użyć odpowiednich instrukcji XSLT:

Example 6.

<xsl:element name="elem-{$sufix}">
  <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>

Task 10.

Create a „filter” tranformation resulting in an XML document of the same structure (as staff.xml), but with employees and departments filtered according to dep and pos parameters.

Zobacz także


Valid XHTML 1.1Valid CSS