XML – ćwiczenia 10: XSLT (3)

Jeszcze o serializacji

Procesor XSLT może, ale nie musi, udostępniać funkcjonalność serializacji – zamiany wynikowego drzewa na ciąg bajtów. Wpływ na sposób serializacji mają parametry serializacji, które można ustawiać:

Pełny opis elementów output i result-document w rekomendacji. Poniżej opis niektórych aspektów serializacji.

Wersja XML lub HTML

Parametr version służy do określenia wersji standardu XML (dla metody XML i XHTML) lub HTML (dla metody HTML).

Deklaracja DOCTYPE

Parametry doctype-public i doctype-system służą do umieszczenia w wyniku deklaracji DOCTYPE. Mają znaczenie przy metodach serializacji XML, XHTML i HTML. Należy ich używać, aby wynik był walidującym się HTML bądź XHTML.

Przykład 1.

Deklaracja output dla XHTML 1.1 (z domyślnym zestawem modułów).

<xsl:output method="xhtml" version="1.0" encoding="utf-8"
	doctype-public="-//W3C//DTD XHTML 1.1//EN"
	doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"/>

Przykład 2.

Deklaracja output dla HTML 4.01 strict.

<xsl:output method="html" version="4.01" encoding="iso-8859-2"
	doctype-public="-//W3C//DTD HTML 4.01//EN"
	doctype-system="http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd"/>

Sekcje CDATA

Parametr serializacji cdata-section-elements może zawierać (rozdzielone spacjami) nazwy elementów w wyniku, których zawartość tekstowa ma być umieszczona w sekcjach CDATA.

Jeśli umieszczenie całego tekstu w jednej sekcji jest niemożliwe, może powstać kilka sekcji.

Mapowanie znaków

W XSLT 2.0 istnieje mechanizm do zastępowania na wyjściu wskazanych znaków innymi napisami. Można zastąpić jedynie znaki z węzłów tekstowych i wartości atrybutów (a nie np. nazw elementów).

Napis wstawiany w miejsce znaku nie jest już w żaden sposób przetwarzany. Wynikowy dokument może więc być niepoprawny składniowo (gdy wstawiany napis zawiera znaki specjalne).

Mechanizm ten nie pozwala na stosowanie różnych character maps w różnych fragmentach dokumentu. W takich sytuacjach przydatna może być instrukcja analyze-string. Uwaga, instrukcja analyze-string działa w warstwie logicznej, podczas gdy mapowanie znaków tylko podczas serializacji.

Przykład 3.

Plik: charmaps1.xsl.

Kopiuje dowolny dokument XML. Przy serializacji zastępuje „polskie znaki” łacińskimi odpowiednikami.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="ascii" use-character-maps="polskie_na_ascii"/>
  
  <xsl:character-map name="polskie_na_ascii">
  	<xsl:output-character character="Ą" string="A"/>
  	<xsl:output-character character="Ć" string="C"/>
  	<!-- ... -->
  	<xsl:output-character character="ź" string="z"/>
  	<xsl:output-character character="ż" string="z"/>
  </xsl:character-map>
  
  <xsl:template match="/">
  	<xsl:copy-of select="."/>
  </xsl:template>
</xsl:stylesheet>

Pomijanie niepotrzebnych deklaracji przestrzeni nazw

Dla metod serializacji XML i XHTML, do wyniku zapisywane są deklaracje wszystkich przestrzeni nazw obowiązujących w elementach, które mają trafić do wyniku. Powoduje to niepotrzebne dodawanie do wyniku deklaracji przestrzeni nazw XML Schema, funkcji XPath i innych.

Aby tego uniknąć, można wykorzystać atrybut exclude-result-prefixes. W atrybucie tym można umieścić:

  • listę rozdzielonych spacjami prefiksów (związanych z przestrzeniami nazw, których nie chcemy wypisywać), dodatkowo na liście może znajdować się napis #default odnoszący się do domyślnej w danym miejscu przestrzeni nazw;
  • napis #all, oznaczający wszystkie przestrzenie nazw obowiązujące w danym miejscu.

Atrybut exclude-result-prefixes może wystąpić:

  • w każdym elemencie XSLT, bez prefiksu xsl,
  • w każdym elemencie wynikowym, z prefiksem xsl (lub innym wskazującym na przestrzeń nazw XSLT),

„Wyłączenie” przestrzeni nazw obowiązuje w całym poddrzewie elementu w którym występuje atrybut exclude-result-prefixes. To rozwiązanie nie gwarantuje, że deklaracja przestrzeni nazw nie pojawi się w wyniku. W szczególności deklaracja pojawi się, jeżeli jakiś element lub atrybut wyniku należy do danej przestrzeni nazw.

Zadanie 1.

Weź jakiś arkusz, który w wyniku zwraca HTML lub XHTML i dodaj odpowiednie informacje o wersji oraz deklaracje DOCTYPE. Sprawdź wynik.

Zadanie 2.

Weź jakiś arkusz, który zawiera deklarację przestrzeni nazw (np. XML Schema) i postaraj się, aby wynik przekształcenia nie zawierał deklaracji tej przestrzeni nazw.

XSLT wynikiem przekształcenia XSTL

XSLT jest też XML-em, a więc może być wyprodukowany jako wynik XSLT. Trzeba zrobić coś, żeby odróżnić elementy XSLT, ktróre mają być interpretowane teraz, od elementów XSLT, które mają być wynikiem transformacji. Umożliwia to deklaracja namespace-alias i specjalna przestrzeń nazw http://www.w3.org/1999/XSL/TransformAlias.

Przykład 4.

Przykład z rekomendacji.

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:fo="http://www.w3.org/1999/XSL/Format"
  xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias">

  <xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
	
  <xsl:template match="/">
    <axsl:stylesheet>
    <xsl:apply-templates/>
    </axsl:stylesheet>
  </xsl:template>
		
  <xsl:template match="block">
    <axsl:template match="{.}">
    <fo:block><axsl:apply-templates/></fo:block>
    </axsl:template>
  </xsl:template>
</xsl:stylesheet>

Zadanie 3.

Napisz XSLT, które na podstawie pliku z opisem tabeli (przykład, DTD) generuje XSLT służące do wizualizacji takich tabel jak w pliku tabela1.xml.

Debugging

Instrukcja message służy do wypisywania informacji o przebiegu transformacji na dodatkowe wyjście (zależne od implementacji).

Element message może posiadać atrybut select lub zawartość, tak jak w przypadku zmiennych. Atrybut terminate równy yes spowoduje przerwanie przekształcenia, gdy obliczenie dojdzie do tej instrukcji.

O czym nie było

XSLT (zwłaszcza w wersji 2.0) to dość rozbudowany standard i na ćwiczeniach nie zmieściły się pewne tematy. Oto niektóre z nich:

  1. Tryby przetwarzania (modes). To zostało uzupełnione tutaj.
  2. Niezbyt precyzyjnie omówiliśmy sprawę przestrzeni nazw. Kopiowanie węzłów przestrzeni nazw do wyniku jest ważną częścią procesu przetwarzania. W różnych miejscach arkusza różne znaczenie mają nazwy bez prefiksów.
  3. Wybieranie elementu po kluczu.
  4. Numerowanie.
  5. Grupowanie.
  6. Wsparcie dla rozszerzania o zewnętrzne funkcje oraz kompatybilność wstecz i w przód.

Valid XHTML 1.1Valid CSS