\chapter{XML -- \acl{XML}}\index{XML} \acf{XML}: \begin{itemize} \item Vorgaben für die Grammatk einer Sprache \item Tags mit Attributen und Inhalten \item jede \acs{XML}-Datei muss/sollte wohlgeformt und gültig sein! \textit{Wohlgeformtheit:} \begin{itemize}[noitemsep] \item Tags immer paarweise, \dash zu jedem Start-Tag gibt es das passende End-Tag \item korrekte Schachtelung der Tags, \dash das zuletzt geöffnete und noch nicht geschlossene Tag muss als erstes geschlossen werden. \item Es gibt genau einen \enquote{Wurzeltag}/\enquote{root-Tag}, \dash genau ein Tag auf oberster Ebene welches das gesamte restliche Dokument enthält. \item[$\Rightarrow$] Kann ohne Kenntnis der konkreten Sprache geprüft werden! \end{itemize} \textit{Gültigkeit:} \begin{itemize}[noitemsep] \item evtl. Name des Wurzelelements \item Elementnamen \item Enthaltenseinsmodell für jedes Element (möglicher Inhalt eines Tags) \item Attributnamen \item Zugehörigkeit von Attributen zu Tags \item Attributtyp (mögliche Attributwerte) \item[$\Rightarrow$] Beschreibung der konkreten Grammatik \end{itemize} Gültigkeit kann anhand einer \acs{DTD} geprüft werden. Eine Alternative dazu ist \acf{XSD} (deutlich mehr Möglichkeiten für Inhaltsmodell und Typisierung, jedoch viel komplexer). \end{itemize} \section{DTD}\index{DTD} Die \acf{DTD} \ldots \begin{itemize}[noitemsep] \item[\ldots] wird referenziert in einer (vollständigen) \code{DOCTYPE}-Deklaration. \item[\ldots] ist textbasiert, aber nicht \acs{XML}-basiert \item[\ldots] besteht aus einer Folge von (also beliebig vielen) Deklarationen (siehe \autoref{lst:xml_deklaration}) in der Variante der \code{DOCTYPE}-Deklaration \end{itemize} \medskip \begin{lstlisting}[label=lst:xml_deklaration,language=HTML5,caption=DOCTYPE- und XML-Deklaration] \end{lstlisting} Für unsere Zwecke reichen zwei Deklarationen: \code{} und \code{} Eine \acs{DTD} wird wie folgend aufgebaut: \subsection{\code{ELEMENT}} Beschreibt ein Element und seinen Inhalt. \bigskip \begin{lstlisting}[language=XML,caption=DTD - ELEMENT] \end{lstlisting} \begin{description} \item[\code{tagname}] Name des Tags oder Elements, bestehend aus Buchstaben (Groß- und Kleinschreibung, case-sensitive), Ziffern, manchen Sonderzeichen (\zB Unterstrich/\enquote{\_}), beginnend nur mit Buchstabe oder Unterstrich. Theoretisch kann der \code{tagname} eine beliebige Länge haben, sollte aber aus praktischen Gründen auf <\,256 Zeichen beschränkt werden. Zudem sollten keine Umlaute und sonstige nationale Sonderzeichen verwendet werden. \item[\code{inhaltsmodell}] Dies kann sein: \hfill \begin{description} \item[\code{EMPTY}] Leeres Inhaltsmodell, \dash der Tag enthält immer genau nichts. \newline Beispiel: \code{} für einen Zeilenumbruch in HTML. \item[\code{ANY}] Beliebiger Inhalt, \dash beliebige Mischung aus Text und Tags (welche aber in der \acs{DTD} deklariert sein müssen). Es gibt kein Beispiel in HTML (und jeder anderen dem Vorleser bekannten Grammatik). $\Rightarrow$ vor dem Inhaltsmodell \enquote{\code{ANY}} warnt der Vorleser! \item[(\code{\#PCDATA})] \enquote{Parsed Character Data} \newline Zeichenfolgen, welche keine Tag-ähnlichen Strukturen enthalten (\zB \enquote{<} mit \code{\<} umschreiben).\newline Beispiel: \code{} \item[sequenz] \code{(tagname1, tagname2[, tagname3\ldots])}\newline Inhalt sind die aufgelisteten Tags (in genau dieser Reihenfolge). Beispiel: \code{} \item[auswahl] \code{(tagname1|tagname2[|tagname3\ldots])}\newline Inhalt ist entweder \code{tagname1} oder \code{tagname2} oder \ldots Es können auch Sequenzen angegeben werden.\newline Beispiel (aus früherem HTML): \code{} \item \code{} \item \code{} \end{itemize} \end{description} \subsection{\code{ATTLIST}} Beschreibt die Attribute eines Elements. \bigskip \begin{lstlisting}[language=XML,caption=DTD -- ATTLIST] |______ auch mehrfach ______| \end{lstlisting} \begin{description} \item[\code{tagname}] Der Tag, für welche die Attribute deklariert werden \item[\code{attrname}] Name des Attributs (derselbe Aufbau und dieselben Einschränkungen wie für \code{tagname}) \item[\code{attrtyp}] \hfill \begin{description} \item[\code{CDATA}] (Character Data), \dash beliebige Zeichenfolge (inkl. Tag-ähnlichen Strukturen, welche hier einfache Zeichenfolgen darstellen. Doppelte Hochkommata müssen mit \html{"} umschrieben werden. \textit{Beispiel}: \xml{} \item[\code{ID}] \label{xml:attrtyp:id} Dokumentenweit eindeutiger Attributwert, Aufbau/Zusammensetzung wie ein \code{tagname} (es ist kein rein numerischer Wert möglich). \textit{Beispiel}: \xml{} \item[\code{IDREF}, \code{IDREFS}] Ein Attributwert vom Typ ID, potentiell mehrere Attributwerte vom Typ \hyperref[xml:attrtyp:id]{ID} (durch Leerzeichen getrennt). \textit{Beispiel} aus \acs{HTML}: Bei Formularen, nicht jedoch bei \html{} \item[\code{NMTOKEN}, \code{NMTOKENS}] \enquote{Nametoken} Aufbau ähnlich wie \code{tagname}, aber jedes der erlaubten Zeichen kann erstes Zeichen sein! So kann \code{123abc} kein Tagname sein, da Tags nicht mit einer Zahl anfangen dürfen, ein \code{NMTOKEN} jedoch schon!\newline Durch Leerzeichen werden mehrere \code{NMTOKEN} voneinander getrennt. \textit{Beispiel} aus \acs{HTML}: \xml{} \item[Aufzählung] \code{nmtoken1|nmtoken2[|nmtoken3\ldots]}\newline Aufzählung aller möglichen Werten vom Typ Nametoken \end{description} \item[Voreinstellung] \hfill \begin{description} \item[\code{"\textit{value}"}] Ein vorgegebener Standardwert vom selben Typ wie \code{attrtyp}. \item[\code{\#IMPLIED}] Gibt an, dass das Attribut optional ist. \item[\code{\#REQUIRED}] Gibt an, dass das Attribut Pflicht ist. \item[\code{\#FIXED "\textit{val}"}] Wenn das Attribut gesetzt wird, darf es nur den Wert \code{val} annehmen. \textit{Beispiel} aus \acs{HTML}: \xml{} Hinweis: Manche Attributtypen, wie \zB \hyperref[xml:attrtyp:id]{ID}, können nur die Voreinstellung \newline \phantom{Hinweis:} \code{\#IMPLIED} oder \code{\#REQUIRED} besitzen. \end{description} \item[weitere Attributtypen] \hfill \begin{itemize}[noitemsep] \item \code{ENTITY}, \code{ENTITIES} \item \code{NOTATION} \end{itemize} \end{description} \newpage \section{Was ist XSLT?}\index{XSLT} \acf{XSLT} ist Teil der \acf{XSL}-Spezifikation. \begin{description} \item[\acs{XSLT}] Eine Sprache zur Umsetzung von \acs{XML} basierten Dokumenten in andere (meist ebenfalls \acs{XML}-basierte) Dokumente. \item[\acf{XPath}] Sprache zur Selektion von Knotenmengen) aus einem \acs{XML}-Dokument \item[XML-FO] Konkrete \acs{XML}-basierte Sprache zur designgetreuen Ausgabe von Dokumenten. \end{description} Wer führt die Transformation durch? \begin{itemize}[noitemsep] \item ein Standalone-Tool: \begin{itemize}[noitemsep] \item \acs{XSL} Transformator (Kommandozeilenaufruf: \code{xslt}) \item xalan \item saxon (auch für Version 2, kommerziell) \end{itemize} \item Server-Side: \begin{itemize}[noitemsep] \item Apache-Projekt Cocoon \item Perl-Modul: AxKit \end{itemize} \item Client-Side: \begin{itemize}[noitemsep] \item gängige WebBrowser (Chrome, Firefox, Edge, Safari, \ldots) \end{itemize} \end{itemize} Die \acs{XSLT}-Sprache ist \acs{XML}-basiert . \autoref{lst:xslt_beispiel} zeigt ein Beispiel. \medskip \begin{lstlisting}[language=XML,caption=XSLT -- Aufbau,label=lst:xslt_beispiel] \end{lstlisting} \begin{Tipp}[frametitle=Editorempfehlung von Herrn Röthig] Editix als FreeEditix. Erhältlich auf: \url{http://editix.com/} \end{Tipp} Wie die Verknüpfung einer \acs{XSLT} mit einem \acs{XML}-Dokument aussieht, zeigt \autoref{lst:xml_xslt} auf Seite~\pageref{lst:xml_xslt}. Mit \xml{} (Bindestrich, kein Doppelpunkt) wird die XSLT aufgerufen. \newpage \begin{lstlisting}[language=XML,caption={Abstraktes XML-Dokument für die Verknüpfung mit XSLT},label=lst:xml_xslt] \end{lstlisting} \subsection{Format der XSLT-Templates} \begin{lstlisting}[language=XML,caption=XSLT Templates] ...... \end{lstlisting} In \autoref{sec:xslt_detailed} wird \acs{XSLT} genauer beschrieben. \section{Der XPath-Ausdruck} Der \acs{XPath}-Ausdruck\footnote{siehe auch \url{https://de.wikipedia.org/wiki/XPath\#Achsen}} \begin{itemize} \item besteht aus einem oder mehreren Lokalisierungssschritte, optional gefolgt von Prädikaten \item mehrere Lokalisierungssschritte werden durch \enquote{/} getrennt \item ein Lokalisierungsschritt besteht aus Achse und Knotentest:\newline \code{axis::node-test[predicate]/\ldots} \end{itemize} \newpage \subsection{Achsen} Achsen geben das \enquote{Verwandtschaftsverhältnis} der aufzusammelnden (gesuchten) zum aktuellen Knoten an. \begin{tabular}{rp{10.8cm}} \code{child}: & direkter Kindsknoten \\ \code{parent}: & der Elternknoten \\ \code{descendent}: & alle Nachfahrenknoten \\ \code{ancestor}: & alle Vorfahrenknoten \\ \code{descendent-or-self}: & Vereinigungsmenge von descendent und self \\ \code{ancestor-or-self}: & Vereinigungsmenge von ancestor und self \\ \code{preceding}: & Vorgängerknoten (ohne ancestor!) \\ \code{following}: & Nachfolgeknoten (ohne descendent!) \\ \code{preceding-sibling}: & ältere Geschwisterknoten (preceding mit demselben parent)\\ \code{following-sibling}: & jüngere Geschwisterknoten (following mit demselben parent)\\ \code{attribute}: & am aktuellen Knoten hängender Attributknoten (alle anderen Achsenausdrücke sammeln nur Element- und keine Attributknoten) \end{tabular} \subsubsection{Verkürzte Schreibweise} Eine Verkürzte Schreibweise der Lokalisierungsschritte für Achsen\footnote{siehe auch \url{https://de.wikipedia.org/wiki/XPath\#Achsen}} \begin{center} \begin{tabular}{rcl} \code{bla} & $\hat{=}$ & \code{child::bla} \\ \code{../bla} & $\hat{=}$ & \code{parent::bla} \\ \code{./} & $\hat{=}$ & \code{self} \\ \code{@fasel} & $\hat{=}$ & \code{attribute::fasel} \\ \end{tabular} \end{center} \subsection{Knotentests} Knotentests schränken die Elementauswahl einer Achse ein: \begin{tabular}{rp{9.5cm}} \code{tagname} & nur die Knoten mit dem entsprechenden \code{tagname} (bzw. bei \code{attribute} der \code{attrname}) \\ \code{*} & Alle Knoten (Wildcard) \\ \code{text()} & Alle Textknoten \\ \code{comment()} & Für Kommentarknoten \\ \code{processing-instruction()} & für Knoten mit \enquote{processing instructions}\\ \end{tabular} \subsection{Prädikate} Durch Angabe von Prädikaten kann das Ergebnis weiter eingeschränkt werden. Prädikate werden in eckige Klammern eingeschlossen und können in beliebiger Zahl hintereinander geschrieben werden, wobei die Reihenfolge wesentlich ist. Prädikate können \acs{XPath}-Ausdrücke enthalten, außerdem kann eine Vielzahl von Funktionen und Operatoren verwendet werden.\footnote{Quelle: \url{https://de.wikipedia.org/wiki/XPath}} \begin{center} \xml{axis::node-test[predicate][/...]} \end{center} Es handelt sich um eine Bedingung an die Knoten, welche erfüllt (\enquote{wahr}) sein muss. \subsubsection{Bedingung} \begin{tabular}{rp{12.4cm}} \acs{XPath}-Ausdruck & nicht-leere Knotenmenge ergibt \enquote{wahr} \\ Zahl & (natürliche Zahl) ergibt den einen Knoten mit der entsprechenden Nummer aus der Knotenmenge beginnend mit 1. \\ \enquote{Vergleich} & zweier \acs{XPath}-Ausdrücke auf Gleichheit (\html{=}), kleiner (\html{\<}), größer (\html{\>}), kleinergleich (\html{\<=}), größergleich (\html{\>=}) \\ Verknüpfen & mit logischen Operatoren \code{and}, \code{or}, \code{not}. \\ Zahlenoperationen & +, -, * \\ \end{tabular} \textsf{\textbf{Funktionen}} \begin{tabular}{lcl} \xml{number(Knotenmenge)} & $\Rightarrow$ & nummerischer Wert des \enquote{Werts} einer Knotenmenge \\ \xml{count(Knotenmenge)} & $\Rightarrow$ & Anzahl Knoten in der Knotenmenge \\ \xml{substring(...)} & $\Rightarrow$ & Teilzeichenkette \\ ... \end{tabular} \section{XSLT - Aufbau}\label{sec:xslt_detailed} \begin{lstlisting}[language=XML,caption=XSL Template] \end{lstlisting} Mögliche Inhalte: \begin{itemize} \item Tags der Zielsprache \newline \html{......} \item Text \enquote{bla fasel blubber}. Whitespace wird auf ein Trennzeichen (\enquote{space}) reduziert. \item Text \xml{ leer zeichen} $\Rightarrow$ Whitespace bleiben erhalten! \item \enquote{Werte} aus dem Quelldokument: \xml{} \item \enquote{Wert} einer Knotenmenge \begin{itemize}[noitemsep] \item Konkatenation der Werte aller Knoten in der Knotenmenge \end{itemize} \item \enquote{Wert} eines Knotens \begin{itemize}[noitemsep] \item bei Textknoten: der Text \item bei Attributknoten: der Text des Wertes des Attributknotens \item bei Elementknoten: rekursive Ermittlung über alle Kindknoten, welche Element- oder Textknoten (\textit{nicht} Attributknoten) sind (Tiefensuche, keine Breitensuche entsprechend der Notation im \acs{XML}-Dokument).\newline \begin{tabular}{lcl} \html{bla fasel blubba} & $\Rightarrow$ & Ein Textknoten an \html{}\\ \html{blafaselblubba} & $\Rightarrow$ & zwei Textknoten an \html{} \end{tabular} \end{itemize} \end{itemize} \subsubsection{Attribute} \html{

Dieser Text ist rot

} $\Rightarrow$ fester Attributwert \xml{} $\Rightarrow$ erzeugt einen Attributknoten am soeben neu geöffneten (noch nicht geschlossenen und noch nicht mit Texten oder Elementknoten als Kinder versehen) Elementknoten. \begin{flushleft} Wert des Attributs als \acs{XPath}-Ausdruck: \newline \xml{} Wert des Attributs als \enquote{errechneter} Wert im Quelltext:\newline \xml{color:} \end{flushleft} \subsection{Aufruf der Templates} \begin{itemize} \item muss explizit erfolgen \item das \code{match}-Attribut sorgt \textit{nicht} für den Aufruf/die Ausführung des Transformators \item der \acs{XSLT} ruft ein Template für den Wurzeltag auf doch \item mittels \xml{} können Templates rekursiv aufgerufen werden \begin{itemize}[noitemsep] \item \xml{} Template Aufruf für alle Kindelemente \item \xml{ \end{lstlisting} \item Sortierung der Knoten bei \xml{} und \xml{} vor Durchgang durch die Knotenmenge:\newline \xml{}\newline als erste Kinder des \xml{} bzw. \xml{}\newline $\Rightarrow$ mehrere Sortierkriterien sind möglich (durch mehrere \xml{} nacheinander) \item weitere Möglichkeiten zu Templates: \medskip \begin{lstlisting}[language=XML,caption=XSLT -- Mode] \end{lstlisting} Aufruf per: \xml{} \item Falls kein passendes selbstgeschriebenes Template existiert, existiert ein Default-Template (\textit{ohne} mode-Attribut), welches alle Textknoten und für Elementknoten Templates rekursiv aufruft. \end{itemize} Zweite Art von Templates: \enquote{named templates}/Templates mit Namen\medskip \begin{lstlisting}[language=XML,caption=XSLT -- Benannte Templates] \end{lstlisting} Aufruf per: \xml{} \newpage \subsection{Parameter und Variablen} Parameter können im Template definiert werden: \newline \xml{Default-Wert} Aufruf mittels: \xml{Wert} innerhalb von \xml{} oder \xml{}. \newline Nutzung per \code{\$Bezeichner} innerhalb von \acs{XPath}-Ausdrücken. \enquote{Variablen} können in einem Block (und auch direkt innerhalb von \xml{} als \enquote{globale Variable}) definiert werden mittels:\newline \xml{Wert} und Verwendung mittels \code{\$Bezeichner}. \textit{Aber}: Der Wert einer \enquote{Variablen} ist nicht veränderbar, sondern fest. Es handelt sich also eher um Konstanten. \xml{} kann auch direkt im \xml{} genutzt werden, um Parameter beim Aufruf des Stylesheets zu übergeben! \subsection{Bedingtes Ausführen} \begin{lstlisting}[language=XML,caption=XSLT -- Bedingtes Ausführen] ... ... \end{lstlisting} Bei der \acs{XSLT} If-Abfrage gibt es kein \code{else}!