Przekształcanie dokumentów XML - XSL
Składowe XSL XSLT (XSL Transformations): XPath (XML Path Language) język opisu przekształceń dokumentów XML oparty na XML pozwala na dopasowywanie wzorców przestrzeń nazw: http://www.w3.org/1999/XSL/Transform, rekomendacja W3C z listopada 1999 r. XPath (XML Path Language) język przeszukiwania danych
Arkusze stylów w przekształceniach XSLT ustawa -> HTML XSL ustawa -> PDF FOSI DSSSL XSLT ustawa -> rozporządzenie Omnimark ustawa (RTF) -> ustawa (XML) CSS
Przekształcanie XSLT Zasady XSLT: Proces przetwarzania wyrażenia XPath określają węzły obowiązywania reguły treść jest przekształcana w przypadku wykonania reguły: tekst i elementy wyświetlane na wyjściu instrukcje XSLT Proces przetwarzania wykonanie reguł dla węzła reguła może wywołać reguły innych węzłów
Struktura XSLT i implementacja Element główny: <xsl:stylesheet version="1.0" mlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:import href="..."/> <xsl:output-method="html"/> <xsl:param name="...">...</xsl:param> ... </xsl:stylesheet> Output-method: xml, html i text Określanie arkusza stylów dla dokumentu: <?xml-stylesheet type="text/xsl" href="..."?>
Przykład dokumentu XSL <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="zamowienie"> <faktura> <nr><xsl:value-of select="@nr"/></nr> <xsl:apply-templates/> </faktura> </xsl:template> <xsl:template match="pozycjaZamowienia"> <xsl:apply-templates/><pozycjaFaktury/> </xsl:template> <xsl:template match="produkt"> <produkt><xsl:apply-templates/></produkt> </xsl:template> </xsl:stylesheet>
Przekształcenie – przykład <zamowienie nr="1/10/2007"> <pozycjaZamowienia> <towar>Monitor</towar> </pozycjaZamowienia> <pozycjaZamowienia> <towar>Drukarka</towar> </pozycjaZamowienia > </zamowienie> <faktura> <nr>1/10/2007</nr> <pozycjaFaktury> <towar>Monitor</towar> </pozycjaFaktury> <pozycjaFaktury> <towar>Drukarka</towar> </ pozycjaFaktury> </faktura>
Reguły wbudowane <xsl:template match="*|/"> <xsl:apply-templates/> </xsl:template> <xsl:template match="text()|@*"> <xsl:value-of select="."/> </xsl:template> <xsl:template match="processing-instruction()|comment()"/>
Generowanie dokumentu Elementy i tekst literalnie podane w przekształceniu Instrukcje generujące: <xsl:value-of select="wyrażenie"/> <xsl:element name="..."/> <xsl:attribute name="..."/> <xsl:text/> <xsl:processing-instruction name="..."/> <xsl:comment/> <xsl:copy/>
Instrukcja warunkowa if <xsl:template match="pozycja"> <tr> <xsl:if wysokosc="kwota>1000"> <xsl:attribute name="rabat">tak</xsl:attribute> </xsl:if> <xsl:apply-templates/> </tr> </xsl:template>
Instrukcja warunkowa choose <xsl:template match="pozycjaZamowienia/towar"> <xsl:variable name="nazwa" select="pozycjaZamowienia/towar"/> <xsl:choose> <xsl:when temp='$nazwa=Telewizor LCD 55cali'> <xsl:element name="tylkoNaZamowienie">tak</xsl:element> </xsl:when> xsl:when temp='$nazwa=Pamięć flash 20 GB'> <xsl:element name="tylkoNaZamowienie">tak</xsl:element> </xsl:when> <xsl:otherwise> xsl:element name="tylkoNaZamowienie">nie</xsl:element> </xsl:otherwise> </xsl:choose> <xsl:text>!</xsl:text> <xsl:apply-templates> </xsl:template>
Pętle <xsl:template match="paragraf"> <ol>§</ol> <xsl:for-each select="punkt"> <li><xsl:value-of select="tekst"/></li> </xsl:for-each> </xsl:template>
Przetwarzanie warunkowe: if <xsl:template match="item"> <tr> <xsl:if test="position() mod 2 = 0"> <xsl:attribute name="bgcolor">yellow</xsl:attribute> </xsl:if> <xsl:apply-templates/> </tr> </xsl:template>
Przetwarzanie warunkowe: choose <xsl:template match="orderedlist/item"> <xsl:variable name="level" select="count(ancestor::orderedlist) mod 3"/> <xsl:choose> <xsl:when test='$level=1'> <xsl:number format="i"/> </xsl:when> <xsl:when test='$level=2'> <xsl:number format="a"/> </xsl:when> <xsl:otherwise> <xsl:number format="1"/> </xsl:otherwise> </xsl:choose> <xsl:text>. </xsl:text> <xsl:apply-templates> </xsl:template>
Pętle <xsl:template match="index"> <h1>Index</h1> <xsl:for-each select="//keyword"> <p><xsl:value-of select="text()"/></p> </xsl:for-each> </xsl:template>
Przetwarzanie XSLT - wejściowe Przetwarzanie według struktury dokumentu źródłowego przechodzimy po strukturze dokumentu źródłowego generujemy fragmenty struktury dokumentu wyjściowego <xsl:template match="..."> ... <xsl:apply-templates/> ... </xsl:template>
Przetwarzanie XSLT - wyjściowe Przetwarzanie według struktury dokumentu wyjściowego jedna główna reguła dla węzła root generowanie struktury dokumentu docelowego wyciąganie odpowiednich wartości z dokumentu źródłowego <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/TR/xhtml1/strict"> <xsl:template match="/"> <html><head><title>Raport wydatków</title></head><body> <h1>Firma: <xsl:value-of select="firma/nazwa"/></h1> <p>Kwota wydatków: <xsl:value-of select="wydatki/kwota"/></p> </body> </html> </xsl:template> </xsl:stylesheet>
Przetwarzanie XSLT - uproszczone Tylko jeden wzorzec dla węzła root Pomijanie elementu stylesheet <html xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/TR/xhtml1/strict" xsl:version="1.0"> <head><title>Raport wydatków</title></head> <body> <h1>Firma: <xsl:value-of select="firma/nazwa"/></h1> <p>Kwota wydatków: <xsl:value-of select="wydatki/kwota"/></p> </body> </html>
Zaawansowane możliwości XSLT Sortowanie węzłów Tryby przetwarzania przełączanie między trybami niezależnie definiowane wzorce dla każdego trybu Zmienne Wzorce nazwane wywoływane jak podprogramy przekazywanie parametrów rekursja
Sortowanie Można stosować w: apply-templates for-each <xsl:template match="klienci"> <h1>Klieci wg kwoty zamówienia</h1> <xsl:apply-templates select="klienci"> <xsl:sort select="kwotaZamowienia" order="ascending"/> </xsl:apply-templates> </xsl:template>
Tryby przetwarzania <xsl:template match="/"> <h1><xsl:value-of select="wyklad/tytul"/></h1> <h2>Tematyka</h2> <xsl:apply-templates mode="klasyczny"/> <xsl:apply-templates/> </xsl:template> <xsl:template match="rozdzial" mode="klasyczny"> <p>"#{generate-id(). <xsl:value-of select="temat"/></p> </xsl:template> <xsl:template match="rozdzial"> <h3>"#{generate-id(). <xsl:value-of select="temat"/></h3> </xsl:template>
Zmienne Podobne w koncepcji do języków programowania: Deklaracja: brak instrukcji przypisania brak efektów ubocznych Deklaracja: <xsl:variable name="..."/> wartość: atrybut select - wyrażenie odpowiedniego typu zawartość elementu - element drzewa wynikowego Użycie: w wyrażeniach: $nazwa <xsl:copy-of select="expression"/>
Użyteczność zmiennych - ograniczenia Wartość można jedynie: skopiować do drzewa wynikowego lub innej zmiennej przekształcić do napisu nie można przekształcić na node set praktycznie niemożliwe obliczenia na zmiennych w kilku wywołaniach Zmienna typu node set <xsl:variable name="b" select="/books"/> <xsl:for-each select="$b/book">...</xsl:for-each> Zmienna typu result tree fragment <xsl:variable name="subtotals"> <xsl:for-each select="/books/book"> <subtl><xsl:value-of select="qty * price"/></subtl> </xsl:for-each> </xsl:variable>
Rekursja w XSLT Sposób na brak „prawdziwych” zmiennych i pętli iteracyjnych Przykład – suma wartości książek <books> <book> <title>Pan Tadeusz</title> <qty>12</qty><price>10.99</price> </book> <book> <title>Mistrz i Małgorzata</title> <qty>1</qty><price>15.99</price> </book> <book> <title>Imię Róży</title> <qty>2</qty><price>6.99</price> </book> </books>
Rekursja w XSLT Przykład – XSLT: <xsl:template name="total-val"> <xsl:param name="list"/> <xsl:choose> <xsl:when test="$list"> <xsl:variable name="first" select="$list[1] "/> <xsl:variable name="rest"> <xsl:call-template name="total-val"> <xsl:with-param name="list" select="$list[position()!=1] "/> </xsl:call-template> </xsl:variable> <xsl:value-of select="$first/qty * $first/price + $rest"/> </xsl:when> <xsl:otherwise>0</xsl:otherwise> </xsl:choose> </xsl:template>
Funkcja node-set() Przekształca fragment drzewa wynikowego w zbiór węzłów (node set). Niedostępna w XSLT jeśli nie ma rozszerzeń: procesora: XT, Saxon, MSXML, biblioteki rozszerzeń EXSLT. <xsl:variable name="subtotals"> <xsl:for-each select="/books/book"> <subtl><xsl:value-of select="qty * price"/></subtl> </xsl:for-each> </xsl:variable> <xsl:value-of select="sum(exsl:node-set($subtotals)/subtl)"/>
Przekształcenia XSL - przykład Dane Dokument <wniosek-urlopowy> <wniosek> <pracownik>Szymon Zioło</pracownik> <rodzaj>wypoczynkowy</rodzaj> <od>2003-06-20</od> <do>2003-06-27</do> <dni-roboczych>6</dni-roboczych> </wniosek> <decyzja> <zgoda>1</zgoda> <zastępca>Jan Kowalski</zastępca> </decyzja> </wniosek-urlopowy> Źródło: Zioło, Sz., XSLT do kwadratu, Software 2.0, nr 6/2003
Przekształcenia XSL - przykład zapisanie metainformacji w szablonie generowanie przekształcenia poprzez szablon <dokument nazwa="wniosek-urlopowy" etykieta="Wniosek urlopowy"> <sekcja nazwa="wniosek" etykieta="Wniosek"> <pole nazwa="pracownik" etykieta="Pracownik:"/> <pole nazwa="rodzaj" etykieta="Rodzaj urlopu:"/> <pole nazwa="od" etykieta="Od dnia:"/> <pole nazwa="do" etykieta="Do dnia:"/> <pole nazwa="dni-roboczych" etykieta="Ilość dni roboczych:"/> </sekcja> <sekcja nazwa="decyzja" etykieta="Decyzja przełożonego"> <pole nazwa="zgoda" etykieta="Zgoda przełożonego:" typ="boolean"/> <pole nazwa="zastępca" etykieta="Zastępca:"/> </sekcja> </dokument>
Przekształcenia XSL - przykład <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:res="http://www.w3.org/1999/XSL/TransformAlias"> <xsl:namespace-alias stylesheet-prefix="res" result-prefix="xsl"/> <xsl:template match="/"> <res:stylesheet version="1.0"> <res:output method="html"/> <xsl:apply-templates/> </res:stylesheet> </xsl:template> <xsl:template match="sekcja"> <res:template match="{@nazwa}"> <p><b><xsl:value-of select="@etykieta"/></b></p> <table><res:apply-templates/></table> </res:template>
Przekształcenia XSL - przykład <xsl:template match="pole"> <res:template match="{@nazwa}"> <tr><td><xsl:value-of select="@etykieta"/></td> <td><b> <xsl:choose> <xsl:when test="@typ='boolean'"> <res:choose> <res:when test="text()='1'">tak</res:when> <res:otherwise>nie</res:otherwise> </res:choose> </xsl:when> <xsl:otherwise> <res:value-of select="text()"/> </xsl:otherwise> </xsl:choose> </b></td></tr> </res:template> <xsl:apply-templates/> </xsl:template> </xsl:stylesheet>
Narzędzia Procesory XSLT: Edytory XSLT: Oracle XML Parser for Java / C / PL-SQL Xalan, Apache (Java, C++) Sablotron (C++, open source) Microsoft XML Core Services (MSXML 4.0) Edytory XSLT: XMLSPY, Altova Xselerator XSL Editor/Debugger, MarrowSoft,
Główne ograniczenia XSLT 1.0 Brak konwersji fragmentów drzewa wynikowego na pełnoprawne zbiory węzłów Brak możliwości generowania wielu dokumentów wyjściowych Brak wsparcia dla grupowania węzłów Brak możliwości definiowania własnych funkcji