From: Edmund H. <so...@us...> - 2002-05-19 18:45:37
|
Update of /cvsroot/xpg-xml/doc In directory usw-pr-cvs1:/tmp/cvs-serv23785 Modified Files: Seminarbericht.gdf Seminarbericht.tex Added Files: Seminartemplate.tex Log Message: seminarbericht update --- NEW FILE: Seminartemplate.tex --- \documentclass[oneside,a4paper,10pt]{report} \usepackage{german} \usepackage{isolatin1} % hyphenation of words with umlauts: results in ugly font! %\usepackage[T1]{fontenc} %\usepackage[latin1]{inputenc} \usepackage[dinodraft,german]{dino} % ---------- change paragraph layout -------------------- \parskip1.2ex % Vertikaler Abstand zwischen Absaetzen \parindent0cm % Nicht einrücken bei neuem Absatz % ---------- change layout of page -------------------- %\usepackage{geometry} %\geometry{a4paper,left=3cm, right=2cm, top=2cm, bottom=1cm} % works quite ok: %\textheight 250mm %\topmargin -20mm %\headheight 10mm %\headsep \baselineskip % distance between header and text %\topskip 10mm % height of header-line %\textwidth 160mm %\oddsidemargin 0mm %\evensidemargin 0mm %\voffset -5mm % ---------- change name of tables -------------------- \renewcommand{\tablename}{Tabelle} \global\def\tableCaption{\tablename} % ------------------- settings for pdf documents ---------------------------- \expandafter\ifx\csname pdfoutput\endcsname\relax \else \hypersetup{backref, pdfauthor={\ehaselwanter}, pdftitle={Seminarbericht XPG-XDML}, pdfsubject={}, % colorlinks=true, %% linkcolor=webgreen, %defined below %% filecolor=webbrown, %defined below %% citecolor=webgreen, %defined below % pdfpagemode=None, a4paper=true, % bookmarksopen=false } % %Define some eye-pleasing colors for this document % % \definecolor{webgreen}{rgb}{0,.5,0} % \definecolor{webbrown}{rgb}{.6,0,0} \fi \setcounter{page}{0} \begin{document} \chapter{Das Framework, ein komponentenbasierter Ansatz} Für das Framework können drei unterschiedliche Gruppen von Benutzern der Software indentifiziert werden: Der {\em Endanwender}, respektive der Autor von Dokumenten, der ausschließlich daran interessiert ist, seine Dokumente gemäß der entsprechenden (\ac{ac:Xml}) Struktur - d. h. unter Verwendung eines bereits genau definierten XML Schemas - zu verfassen. Der {\em Dokument Entwickler}, der verschiedene Dokumentarten klassifiziert und die jeweiligen Schematas dazu festlegt und die entsprechendern Transformationen entwickelt, mit denen er das Basislayout der Zielformate festlegt. Und der {\em Systementwickler}, der den Kern des Systems entwirft und ihm weitere Funktionalität hinzufügen kann. Um dem zu entsprechen wurde ein Framework konzipiert, das es erlaubt auf verschiedene Art und Weise erweitert und eingesetzt zu werden. \section{Ein einfaches Beispiel} Um nun die Grundstrukturen und Vorgangsweisen des Frameworks zu skizzieren betrachten wir vorerst ein einfaches Beispiel. Wir wollen ein Eingabedokument das im XML-Format vorliegen soll in ein konkretes Zielformat, in diesem Fall wählen wir HTML, übersetzten. Als erster Schritt muß eine Beschreibung des Sourcedokumentes - sozusagen einer Dokumentenklasse - modelliert werden. Der Einfachheit halber wird in diesem nur ein Element \texttt{<doc>} und ein Element \texttt{<title>} verarbeitet. Die Information, welche mit dem \texttt{<title>} Element umschlossen wird, soll in das HTML-Ausgabedokument übernommen werden. In XML Syntax sieht dieses Beispiel dann folgendermaßen aus: \texttt{simpledoc.xml}: \begin{verbatim} <doc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="simpledoc.xsd"> <title>Title Definition</title> </doc> \end{verbatim} Um garantieren zu können, dass die Verarbeitung dieses Dokumentes durch das Framework korrekt abläuft, muss zu dem Eingabedokument ein XML-Schema (siehe \ref{subsec:Schema}, S. \pageref{subsec:Schema}) entworfen werden. Ausserdem ist damit eine ganze Klasse von Dokumenten spezifiziert. \texttt{simpledoc.xsd}: \begin{verbatim} <?xml version="1.0" standalone="no"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="doc"> <xsd:complexType> <xsd:all> <xsd:element name="title" type="xsd:string"/> </xsd:all> </xsd:complexType> </xsd:element> </xsd:schema> \end{verbatim} Betrachten wir nun die Abarbeitung dieses Dokumentes im Hinblick auf unser Ziel, daraus ein HTML Dokument zu machen. Im Eingabedokument sind durch seine (XML) Struktur folgende Informationen implizit enthalten: \begin{itemize} \item \texttt{<doc>} - Drei Informationen: Erstens, dass das Dokument begonnen hat, zweitens das Auftreten eines \texttt{<doc>} Elementes und drittens, dass das File \texttt{simpledoc.xsd} das zugehörige XML-Schema ist. \item \texttt{<title>} Das Auftreten des \texttt{<title>}-Elementes \item ``\texttt{Title Definition}'' - Alle Zeichen zwischen dem \texttt{<title>} und dem \texttt{</title>} Element, in diesem Fall die Zeichenfolge ``\texttt{Title Definition}'' \item \texttt{</title>} - Das Auftreten des \texttt{</title>}-Elementes \item \texttt{</doc>} - Das Auftreten des \texttt{</doc>}-Elementes und das Ende des Dokumentes \end{itemize} Bei einer sequentiellen Abarbeitung dem sogenannten {\em Parsen} des Dokumentes kann man die Folge der Informationen als Folge von Ereignissen (Events), die etwas bewirken können, auffassen (im Detail siehe \ref{subsec:DerParser}, S.\pageref{subsec:DerParser}). Dieses XML-Dokument, das dem zugehörigem XML-Schema genügt, ist nur ein Dokument aus der Menge der Dokumente die mit dem XML-Schema beschrieben werden. Wir müssen auf alle Kombinationen respektive Reihenfolgen dieser Ereignisse reagieren können, die das entworfene XML-Schema eindeutig und überprüfbar vorgibt. Somit ergibt sich für diese Dokumentenklasse das in Abbildung \ref{fig:statemachine} dargestellte Ablaufdiagramm, das alle möglichen und gültigen Pfade enthält. \image[1.0]{images/bspSimple}{Das Ablaufdiagramm zum \texttt{<doc>} Beispiel }{}{fig:statemachine} Das alleine stellt allerdings nur eine theoretische Betrachtung aller gewünschten Abläufe der Ereignisse dar. Wie man am Ablaufdiagramm leicht erkennt, kann dieses Verhalten mit einem dem Diagramm entsprechendem endlichen Automaten (Finite-State-Machine) FIXXME Referenz erreicht werden. Dabei bilden die Ereignisse die auslösenden Momente (Trigger, Transitionen) von einem gültigen Zwischenzustand (State) zum nächsten gültigen Zwischenzustand. Diese Zustände müssen nicht zwingend verschieden sein. Jedes Dokument wird zumindest zwei {\em ausgezeichnete} Zustände haben, den Dokument-Start-Zustand und den Dokument-Ende-Zustand. Die Statemachine ist das Kernstück dieses Frameworks (siehe \ref{sec:DasDesigndesFrameworks}, S. \pageref{sec:DasDesigndesFrameworks}). Es ist nun eine von obigem Schema abgeleitete Beschreibung dieser erforderlich, damit sie dann das Dokument (respektive die ganze mit obigem Schema beschriebene Dokumentenart) {\em versteht}. Diese Beschreibung erfolgt zweckmäßiger Weise auch mittels eines validierbarem XML-Dokumentes, da wir verschiedene Dokumentklassen verarbeiten wollen und damit auch entsprechend unterschiedliche endliche Automaten aufbauen müssen. Für die Validierung muss diese Beschreibung auch einem XML-Schema genügen, dem XML-Schema für die Statemachine (im Anhang auf Seite \pageref{sec:Schema}). Bereits an diesem kleinem Beispiel kann man erkennen, dass die Anzahl der Zustände schnell sehr umfangreich wird. Allerdings muss dies nur einmal für eine Dokumentklasse gemacht werden. Nachfolgend sind die wesentlichen Abschnitte dieses XML-Dokumentes, dem sogenannten Konfigurationsfile der Statemaschine, für diese Dokumentklasse, dargestellt. 1. Angabe des Schemas % \footnotesize \begin{verbatim} <?xml version="1.0" standalone="no"?> <statemachine xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="StateMachineConfig.xsd"> \end{verbatim} 2. Die Liste aller gültigen Zustände. Der Startzustand muss besonders ausgezeichnet sein, damit man einen gültigen Ausgangszustand der Statemachine hat. \begin{verbatim} <states> <startstate>STATE_TOP_LEVEL_FILE</startstate> <state>STATE_TOP_LEVEL_DOC</state> <state>STATE_DOC_TITLE_DEF</state> <state>STATE_FINISHED</state> </states> \end{verbatim} 3. Die Liste aller zugelassenen Transitionen. Die Zustände des endlichen Automaten werden vor den Transitionen bekanntgegeben, damit schon beim Parsen festgestellt werden kann, ob die Transitionen eine gültige Zustansänderung beschreiben. \begin{verbatim} <transitions> <transition> <beginstate>STATE_TOP_LEVEL_FILE</beginstate> <nextstate>STATE_TOP_LEVEL_DOC</nextstate> <element type="start">doc</element> <classname>WriteGeneralHeaderTransition</classname> </transition> . . . <transition> <beginstate>STATE_TOP_LEVEL_FILE</beginstate> <nextstate>STATE_FINISHED</nextstate> <element type="enddoc" /> <classname>StopMachineTransition</classname> </transition> </transitions> </statemachine> \end{verbatim} %\normalsize Sämtliche für die Übersetzung des XML-Sourcedokuments notwendigen Dokumente (Schemata, Konfigurationsfile, ...) sind nun vorhanden. Ziel unserer Bemühungen ist es aber aus einem XML-Eingabedokument ein HTML-Ausgabedokument zu machen. Es fehlt also noch etwas entscheidendes, nämlich die Anweisungen, welche die Generierung des Outputs in der Zielsprache - für dieses kleine Beispiel HTML - übernehmen. Diese Anweisungen werden bei der Beschreibung Transitionen als Klassenname angegeben (im Detail siehe \ref{subsec:Transitions} , S.\pageref{subsec:Transitions}). Die hier benötigten Anweisungen bzw. Klassen sind nun: \begin{description} \item [PrimitiveTransition] Diese implementiert nur das Interface einer Transition und trägt weiter nichts zum Output bei. Sie wird benötigt um von einem Zustand der Statemachine in einen anderen zu wechseln. \item [WriteGeneralHeaderTransition] Diese schreibt den allgemeinen Kopf des Outputdokuments. Im diesem Beispiel mit \ac{ac:Html} als Zielsprache ist dies das öffnende \texttt{<html>} Tag, das komplette \texttt{<head>} Element und das öffnende \texttt{<body>} Tag. \item [StoreDocTitleTransition] Diese speichert den Inhalt des \texttt{<title>} Elements des \ac{ac:Xml} Eingabedokuments (im Detail siehe \ref{subsec:VerwaltungVonInputdaten}, S.\pageref{subsec:VerwaltungVonInputdaten}). \item [WriteDocTitleTransition] Diese schreibt den Inhalt des \texttt{<title>} Elements des \ac{ac:Xml} Source in den Output, eingebettet in ein \texttt{<h1>} Element. \item [WriteGeneralFooterTransition] Diese schreibt nun das generelle Dokumentende des Outputs; für das \ac{ac:Html} Beispiel ist dies das schließende \texttt{</body>} und das schließende \texttt{</html>} Tag. \item [StopMachineTransition] Diese wird aufgerufen, wenn der komplette Input abgearbeitet wurde (EOF bei einem Eingabedokument). Sie stoppt die Statemachine und stellt somit sicher dass das Framework korrekt terminieren kann. \end{description} Mittels dem Konfigurationsfile wird nun also der Statemachine beigebracht Sourcedokumente, welche dem entsprechenden Schema genügen, zu {\em verstehen}. Mit Hilfe der entsprechenden Transitionen generiert die Statemachine beim Abarbeiten des Inputs den gewünschten Output. Für dieses einfache Beispiel kann der generierte Output dann folgendermaßen aussehen: \begin{verbatim} <html> <head> <title></title> </head> <body> <h1>Title Definition</h1> </body> </html> \end{verbatim} \section{Das Design des Frameworks} \label{sec:DasDesigndesFrameworks} Bereits für das vorangehende einfache Beispiel ist eine gewisser Aufwand notwendig, um zu dem gewünschten Ergebnis zu gelangen. Zusätzlich zu dem eigentlich zu übersetzenden Eingabedokument mußten ein XML-Schema für dieses, ein XML-Schema für die Statemaschine, ein Konfigurationsfile und eine Reihe von Transitionen erstellt werden. Es wurde allerdings der gesamte Aufwand aller Benutzergruppen {\em Endanwender}, {\em Dokument Entwickler} und {\em Systementwickler} dargestellt. Unterteilt man nun wieder in diese drei einführend erkannten Gruppen von Benutzern der Software, dann relativiert sich dieser Aufwand recht rasch wieder: Der {\em Systementwickler}, welcher den funktionalen Kern des Frameworks entwickelt, entwirft dazu auch das entsprechende XML-Schema für das Konfigurationsfile der Statemachine. Dieses Statemachineschema wird zusammen mit dem Kern des System nur einmal geschrieben und ändert sich in folge nur bei gravierenden Eingriffen in die Kernfunktionalität des Systems. Der {\em Dokument Entwickler} schreibt danach für eine ganze Klasse von Dokumenten ein dem Statemachineschema genügendes Konfigurationsfile mit welchem dann der Statemachine beigebracht werden soll, Dokumente dieser Klasse zu {\em verstehen}. Korrespondierend zu dem Konfigurationsfile entwickelt dieser ein XML-Schema für die Dokumente dieser Klasse. Auch entwickelt er die notwendigen Transitionen (siehe auch \ref{subsec:Transitions}) die den Output für diese Klasse von Dokumenten generieren sollen. Somit kreiert er für eine bestimmte Klasse von Sourcedokumenten ein komplettes wiederverwendbares Package (siehe \ref{sec:Packages}) - bestehend aus XML-Schema der Dokumentklasse, Konfigurationsfile der Statemaschine und Transitionen - rumd um den Systemkern. Der {\em Endanwender} nimmt nun Systemkern und eines dieser Packages und muß nur das Sourcedokument erstellen - dieses muß alelrdings dem im ausgewählten Package enthaltenen Schema entsprechen - und kann somit den Output in der gewünschten Zielsprache generieren. Ähnlich der Unterteilung in verschiedene Benutzergruppen des Frameworks kann dieses nun auch aus funktionaler Sichtweise dreigeteilt werden (siehe Abbildung \ref{fig:Design}). \image[1.0]{images/Design}{Framework: funktionale Darstellung}{}{fig:Design} Der {\em Parser} (siehe \ref{subsec:DerParser}, S.\pageref{subsec:DerParser}) welcher das Sourcedokument parst und diesem entsprechend Events generiert. Die {\em Statemachine} (siehe \ref{sec:Statemachine}) welche diese Events dann verarbeitet und dem entsprechend die {\em Transitionen} (siehe \ref{subsec:Transitions}) triggert, mit deren Hilfe schlußendlich der gewünschte Output erzeugt wird. Bei den Transitionen kann man außerdem noch unterscheiden zwischen sogenannten {\em Core }-Transitionen - das sind gleichsam eine kleine Anzahl von Basistransitionen, die direkt zum Framework gehören - und den Transitionen in den einzelnen {\em Packages} (siehe \ref{sec:Packages}) zur jeweils entsprechenden Klasse von Dokumenten die damit verarbeitet werden soll. \subsection{Der Parser} \label{subsec:DerParser} Dieser Teil des Frameworks übernimmt das Einlesen, sprich Parsen, des XML-Sourcedokuments. Da beim Parsen mit \ac{ac:Dom} - Technologie die Gefahr besteht, dass es bei großen Dokumenten zu einem Speicherproblem kommen kann, da der gesamte \ac{ac:Dom}-Baum des Dokumentes einfach zu groß werden könnte, verwenden wir einen ereignisbasierten Parser. Wir haben uns für SAX2 und Xerces, den XML-Parser der das \ac{ac:Sax} - Interface implementiert entschieden (siehe auch \ref{subsec:Sax}, S.\pageref{subsec:Sax})\cite{xerces}\cite{sax}. Dazu wird über die \texttt{XMLReaderFactory} der Xerces-SAXParser als \texttt{XMLReader} erzeugt. Dem \texttt{XMLReader} muss nun ein Handler der das \texttt{DocumentHandler}-Interface implementiert bzw. von von der Referenzimplementierung, der Klasse \texttt{DefaultHandler} abgeleitet ist, bekanntgegeben werden. Wir haben einen \texttt{XMLHandler}, der \texttt{DefaultHandler} abgeleitet ist, implementiert. Hier wird die Verbindung zur \texttt{Statemachine} hergestellt, indem der \texttt{XMLReader} die Callback-Methoden des \texttt{XMLHandlers} aufruft, in denen wiederum die Callback-Methode der \texttt{Statemaschine} aufgerufen wird. Für ein korrektes Funktionieren des Frameworks muss beim Parsen festgestellt werden, ob das Eingabedokument korrekt ist. Technisch kann das auf die zwei vorgestellten Arten, mithilfe einer DTD (siehe \ref{subsec:Dtd}, S.\pageref{subsec:Dtd}) oder eines XML-Schemas (siehe \ref{subsec:Schema}, S.\pageref{subsec:Schema}) geschehen. Aufgrund der Vorteile des XML-Schemas gegenüber einer DTD verwenden wir hier XML-Schema zur Spezifikation der Eingabedokumente. Somit muss der \texttt{XMLReader} noch auf Validierung mit XML-Schema gestellt werden, damit wir auf fehlerhafte Eingabedokumente reagieren können (siehe \ref{sec:Fehlerbehandlung}, S.\pageref{sec:Fehlerbehandlung}). Hierfür sieht SAX2 die Methode \texttt{setFeature} der Klasse \texttt{XMLReader} vor. Die entsprechenden Attribute für Validierung und XML-Schema sind nun: \begin{verbatim} http://xml.org/sax/features/validation http://apache.org/xml/features/validation/schema \end{verbatim} Der Parser leitet nun die Events XML-Input an die Statemachine weiter. \subsection{Die Statemachine} \label{sec:Statemachine} Die Statemachine ist die Implementierung eines deterministischen endlichen Automaten. Durch den XML-Input kommt es zu einer Zustandstransformation (Transition). Dadurch ergibt sich die gewünschte Ablaufsteuerung der Verarbeitung der SAX-Events, die durch das Parsen des XML-Eingabedokumentes hervorgerufen werden. Zusätzlich wird bei den Transitionen die Ausführung des zu Ihnen gebundenen Java Codes ausgelöst. Dies stellt somit einen gewünschten Seiteneffekt der Statemachine dar. Da der gebundene Java Code beliebig und ``außerhalb'' der Statemachine Implementierung ist, können damit SAX eventgesteuert Aktionen ausgeführt werden, die die Inputdaten (FIXXME und alle anderen....) verarbeiten. FIXXME: Referenz Statemachine / endlicher Automat \subsection{Schemata und Konfigurationsfile} Aus dem gewünschten Schema des zu verarbeitenden Dokumentes muss eine Konfiguration der verarbeitenden Statemachine, die dem Schema der Statemachine genügt, abgeleitet werden. \subsection{Verwaltung von Inputdaten} \label{subsec:VerwaltungVonInputdaten} FIXXME: XMLElement / Stack und DataObject erklären \subsection{Die Transitionen} \label{subsec:Transitions} Die Transitionen erledigen die Hauptarbeit und generieren im Endeffekt dann den Output. Interface der Transitionen: \begin{verbatim} public interface Transition { public String transitionTriggered(Input input, State from_state, State to_state, StateMachine machine, DataObject data) throws Exception; } \end{verbatim} Aus funktioneller Sicht kann man die Transitionen in speichernde und schreibende unterteilen: die speichernden legen den aktuellen Input (eventuell in modifizierter Form) im DataObject ab und die schreibenden sind im Gegensatz dazu verantwortlich aus all den Informationen im DataObject sequentiell den gewünschten Output zu generieren. Weiters gibt es sogenannte {\em Core }-Transitionen, welche zum Kern des Systems gehören (im Gegensatz zu den Transitionen in den einzelnen Packages). Diese haben entweder nur eine gewisse Basisfunktionalität oder werden in der Initialisierungsphase benötigt. Core-Transitionen sind nun folgende: \begin{description} \item [PrimitiveTransition] \item [IgnoreCharsTransition] \item [RegisterStateTransition] \item [RegisterStartStateTransition] \item [RegisterTransitionTransition] \item [SetSearchPathTransition] \item [StoreDataTransition] \item [ClassLoaderTransition] \item [StopMachineTransition] \end{description} \subsection{Packages} \label{sec:Packages} \subsection{Konfiguration} Um mit einer Statemachine arbeiten zu können muss, diese zuerst aufgebaut werden. Das heißt es müssen die zulässigen States und die dazugehörigen Transitionen erst registriert werden. Diese sind jedoch abhängig von der gewünschten Funktionsweise jeweils unterschiedlich. Es wird also eine Möglichkeit benötigt die Statemachine zu beschreiben. Um möglichst flexibel zu bleiben, passiert das mit einem Konfigurationsdokument, welches dem Statemachine Schema genügen muss. Das Konfigurationsdokument wird, wie schon bei der Erklärung der SAX API {\em eventbasiert} geparst. Zum Registrieren der States und Transitionen in der Statemachine gibt es nun zwei Alternativen: entweder wird dies direkt in die Callbacks des SAX Parsers hineinverpackt, oder man verwendet dazu wiederum eine Statemachine, welche jedoch ``hardcodiert'' ist. Wir haben uns entschlossen die zweite Alternative mit der ``hardcodierten'' Statemachine, die sogenannte {\em InitStateMachine }, weiterzuverfolgen. Im Konfigurationsdokument stehen alle notwendigen Informationen, um die gewünschte Statemachine aufbauen zu können. Das Schema für das Konfigurationsdokument ist unabhängig von den unterschiedlichen Verwendungszwecken immer das selbe. Da die Verarbeitung des Konfigurationsdokuments hardcodiert ist bedingt eine Änderung dieses Schemas einen Eingriff in den Sourcecode! Das Konfigurationsdokument enthält die States für die Statemachine, inklusive einem ausgezeichnetem Startstate. Weiters enthält es die Transitionen, wobei jede Transition einen Beginstate, einen Nextstate, ein Element, durch welches sie getriggert wird, und die Aktion als Klassenname. Wobei der Klassenname wegfallen kann, wenn keine Aktion benötigt wird, dies entspricht dann einer DefaultTransition. Weiters muss im Konfigurationsdokument noch der Pfad für die Transitionen angegeben werden. Genau genommen werden allerdings nicht direkt die entsprechenden Aktionen/Klassen registriert sondern nur eine sogenannte {\em ClassLoaderTransition } welche den Namen der entsprechenden Klasse dann beinhaltet und bei Erhalt eines Triggers dann mittels dem {\em Factory Pattern} FIXXME (Gamma et al) diese zur Laufzeit nachlädt und sogleich einen Trigger auf diese setzt, sie also auch gleich ausführt. Somit werden die Klassen erst beim Auftreten eines entsprechenden Triggers nachgeladen. Auch wenn eine Transition mehrmals benötigt wird wird sie nur einmalig nachgeladen, da diese Implementierung des Factory Patterns in Java intern ein Caching betreibt. \section{Fehlerbehandlung} \label{sec:Fehlerbehandlung} Bei der Verarbeitung von Dokumenten können verschiedene Arten von Fehlern auftreten. Einerseits Fehler des Parsers und der Statemachine die aufgrund von ``korrupten`` Inputdateien auftreten koennen, andereseits Fehler die durch Transitionen erzeugt werden. \subsection{Parser Fehler} Das \ac{ac:W3c} hat in der {\em XML Recommandation 1.0} \cite{rec-xml} zwei Arten von Fehlern definiert. \begin{description} \item [error:] Eine Verletzung der XML Spezifikation, es sind die Konsiquenzen nicht definiert. Ein Beispiel hierfür ist bei einem Validierenden Parser, wenn das Dokument nicht dem angegebnen Schema bzw. der \ac{ac:Dtd} entspricht. \item [fatal error:] Eine Verletzung der XML Spezifaktion, es darf die normale Verabeitung vom Parser nicht fortgesetzt werden. Diese Art von Fehler tritt zum Beispiel auf wenn ein XML Dokument nicht wohlgeformt ist. \end{description} \textbf{FIXXXME --> thick red line} \\ Das SAX API stellt zur Verarbeitung dieser Fehler das Interface \texttt{ErrorHandler} zur Verfügung. Um von einer Applikation ein eigene Fehlerbehandlung zu gewährleisten, muss der \texttt{ErrorHandler} beim XML Reader registiert werden. Es werden dann vom SAX Parser Fehler an diesen Handler gemeldet. Es müssen in diesem Interface die zwei Callback Funtktionen \texttt{error} und \texttt{fatalError} implementiert werden.Die Informationen über den Aufgetretenen Fehler werden den beiden Funktionen mittels \texttt{SAXParseException} als Parameter übergeben. Das Standardverhalten dieser Beiden Funktionen ist, dass sie gar nichts tun. Dies ist aber im Fall der Statemachine ein nicht wünschenswertes verhalten, da ja vom \texttt{???Handler} die Trigger fuer die einzelnen Transitionen ausgelöst werden und ein nicht wohlgeformtes bzw. nicht gültiges XML Dokument falsche oder nicht Vorhandene Transitionen auslösen kann. Es werden deshalb Fehler ausgegeben, die Verarbeitung des Inputs abgebrochen und die Statemachine ``sauber`` heruntergefahren. \textbf{end FIXXXME --> thick red line} \\ \subsection{Statemachine Fehler} Da ja die Statemachine dynamisch in Abhängigkeit der zu Verarbeiteten Dokumentklassen aufgebaut wird können auch hier verschiedene Fehler auftreten, die noch nicht vom Parser entdeckt und an das Framework gemeldet wurden. Hierbei handelt es sich um Fehler die bei der Initalisierung der Statemachine durch eine Konfigurationsdatei auftreten können, welche zwar dem XML Schema für diese Dokumentklasse entspricht jedoch trotzdem nicht korrekt verarbeitet wird. Solche Fehler sind zum Beispiel der Versuch mehrere States mit dem gleichen Namen zu registrieren, oder die Registrierung einer Transition deren Anfangs- und/oder der Endstate nicht registriert wurde. Da durch ein XML Schema nur die Struktur eines Dokumentes vorgegeben, der Inhalt jedoch nur rudimentär eingschränkt werden kann (siehe Restrictionbase XMLSchema ??? Recomendation) können diese Fehler nicht vom Parser gefunden werden. Um die Transparenz, wie das Framework arbeitet, für den Dokumententwickler zu wahren, wurde die Designentscheidung getroffen, dass die Initialisierung der Statemachine bei einem solchen Fehler abgebrochen wird. Es könnte beim Versuch einen solchen Fehler bei der Initialsierung auszubessern nicht garantiert werden, dass die Statemachine das geplante Verhalten zeigt. Bei der eigentlichen Verarbeitung kann es jedoch auch zu Eingaben kommen die von der Statemachine nicht interpretiert werden können. Ein solcher Fehler tritt auf, wenn es für einen Input im gerade aktuellen State keine geine gültige Transitionen gibt. Dies bewirkt, dass das Dokument nicht korrekt bis zum Ende verarbeitet werden kann und deshalb wird ein solcher Fehler wie ein Parser Fehler behandelt. Warum kann dies nun auftreten wo doch der Parser validierend agiert? Einer der Gründe ist, dass die Statemachine für eine Dokumentklasse initialisiert wurde die nicht dem XML - Schema des zu verarbeitenden Dokuments entspricht. Für den den Parser ist dieses Dokument jedoch valide, die Statemachine versteht es jedoch nicht und liefert dann diesen Fehler. \textbf{FIXXXME --> thick red line} \\ Die Transitionen können auch Fehler verursachen, wo thalze aber nicht weiss welche. \textbf{FIXXXME --> thick red line} \\ \chapter{Anwendungsbeispiele} \label{sec:Anwendungsbeispiele} \section{Konfiguration} Ein Einsatzbeispiel für das Konzept der Statemaschine findet sich bereits im Gesamtkonzept des komponentenbasierten Ansatzes zur Übersetzung von Dokumenten in andere Formate mittels einer Statemachine wieder. Da die hier zur Übersetzung verwendete Statemachine sehr flexibel sein muß - sie muß mit unterschiedlichen Eingangsformaten (vorerst unterschiedlichen XML-Schemata) arbeiten und in unterschiedliche Ausgansformate (z.B. \ac{ac:Html}, LaTeX, ...) übersetzen können - ist es unmöglich bereits zur Compilezeit alle möglichen Stati und Transitionen berücksichtigen zu können. Das bedeutet die Konfiguration dieser Statemachine - das Registrieren der benötigten Stati und Transitionen - kann erst zur Laufzeit erfolgen. Die notwendigen Informationen zur Konfiguration werden in ein XML-File - das sogenannte {\em Configfile } - geschrieben, welches einem vorgegebenen Schema (dem {\em Configfile-Schema }) gehorcht. Dieses wird mittels SAX geparst, welcher seine Events an eine (Konfigurations-)Statemachine weitersendet, welche nun allerdings hardcodiert und mit den enthaltenen Stati und Transitionen an das vorgegebene Schema angepasst ist. Diese Konfigurations-Statemachine übernimmt nun das Registrieren der notweendigen Stati und Transitionen in der für die Übersetzung benötigten Statemachine; das heißt das Ergebnis der Konfigurationstatemachine ist wiederum eine Statemachine, welche nun flexibel konfiguriert ist und zum Übersetzen von XML-Dokumenten in beliebige Formate eingesetzt werden kann. \section{Problemstellung XPGForms} Ein gängiges Problem in der Webseitengestaltung bzw. Programmierung ist das Verarbeiten von Daten, die vom User eingegeben werden. Es ist sinnvoll, einen generellen Ansatz für dieses Problem zu schaffen, da die Abläufe immer dieselben sind, nur die Repräsentation und die verwendeten Daten ändern sich. Es wäre vom Vorteil, wenn ein Framework existieren würde, dass diese Abläufe umfasst; es sollte für die jeweiligen Projekte bzw. Webseiten nur noch eine Datenbeschreibung vom Programmierer in einer geeigneten Form modelliert werden. Der Grafiker kann dazu parallel Templates entwerfen, in die per Platzhalter die Datenfelder eingefügt werden können. Eine geeignete Lösung wäre dafür, die Datenfelder in einem geeigneten Format (XML bzw. XML Schema bieten sich an) zu beschreiben. Durch verschiedene Transformationen wird eine Ablaufsteuerung generiert, die das User Interface für den Benutzer bereitstellt. Die Erzeugung der eigentlichen Web Formulare passiert also automatisiert. Dies hat nicht nur den Vorteil einer Zeitersparnis, sondern durch die Formalisierung des Prozesses werden Fehlerquellen der Implementierung minimiert. Die XPG State Machine kommt an dem Punkt der Umwandlung von XML in PHP ins Spiel; von einer Quellensprache (XML) wird in eine mögliche Zielsprache (PHP) transformiert. Es wäre jedoch leicht möglich, auch z. B. JSP oder ASP damit zu erzeugen. \section{\LaTeX: flexible Handhabung ganzer Dokumentblöcke} Während der Erstellung größerer Dokumente kann es immer wieder vorkommen, dass es notwendig ist Teile eines Dokuments umzustrukturieren, ganze Blöcke des Dokuments zu verschieben. Dabei kann es passieren, dass aus einem ursprünglich eigenem Kapitel nunmehr ein Unterkapitel wird oder umgekehrt aus einem anfangs nur als kleines Unterkapitel gedachtem Block nun ein eigenes großes Kapitel wird. Das bedeutet aber, dass Änderungen in der Dokumentenhierarchie vorgenommen werden. Nun ist jedoch in Textbeschreibungssprachen wie \ac{ac:Latex}, dass diese Heirarchie eines Dokuments eine sehr genau vorgegebene Form haben muß - bei \ac{ac:Latex} sind dies der Reihe nach {\em part, chapter, section, subsection, subsubsection, paragraph, subparagraph}. Dies bedeutet nun aber, wenn bei solchen Umstrukturierungen aus Unterkapiteln eigene Kapitel werden (und analog umgekehrt), dass diese Modifikationen der Dokumenthierarchie händisch nachgebessert werden müssen: aus einem {\em section} wird ein {\em chapter}, aus dem darin enthaltenen {\em subsection} wird ein {\em section} und gleich weiter im ganzen verschobenen Block (respektive umgekehrt wenn aus einem Kapitel ein Unterkapitel wird). Dieses händische Nachbessern wird obsolet, wenn man in der Dokumenthierarchie nur ein Element (z.B. {\em section }) kennt, unabhängig von derjeweiligen Hierarchieebene - man dieses also beliebig ineinander verschachteln kann. Aus der Tiefe dieser Verschachtelung erhält man dann die Ebene der Hierarchie für die Übersetzung in ein Zielformat (wie \ac{ac:Latex }) in dem man je Ebene einen unterschiedlichen Bezeichner hat. Eine solche Dokumentenhierarchie kann nun zum Beispiel ein Aussehen wie folgt haben: \begin{verbatim} <document> <section> <title>1. Kapitel</title> <para> ... </para> </section> <section> <title>2. Kapitel</title> <para> ... </para> <section> <title>1. Abschnitt</title> <para> ... </para> </section> <section> <title>2. Abschnitt</title> <para> ... </para> </section> </section> </document> \end{verbatim} Der eigentliche Inhalt der einzelnen Abschnitte befindet sich hier in den \texttt{<para>} Elementen, und wird entsprechend er weiters darin enthaltenen Elemente ins Zielformat übersetzt. Die \texttt{<title>} Elemente enthalten die überschriften der einzelnen (Unter-)Kapitel. Für die \texttt{<section>} Elemente wir die jeweile Verschachtelungstiefe akkumuliert (d.h. bei einen Starttag um eins erhöht und beim Endtag wieder um eins erniedrigt) und entsprechend dieser dann der entsprechende Bezeichner in der Zielsprache ausgewählt. Zu obigem Beispiel kann nun die dazugehörige Dokumentenhierarchie in \ac{ac:Latex} folgendermaßen aussehen: \begin{verbatim} \begin{document} \section{1. Kapitel} ... \section{2. Kapitel} ... \subsection{1. Abschnitt} ... \subsection{2. Abschnitt} ... \end{document} \end{verbatim} \section{Rechnen} Häufig kommt es vor, dann man eine ganze Menge von Daten als Input hat, sich jedoch nicht für diese gesamte Datenflut interessiert, sondern nur ein paar davon abgeleitete Daten benötigt. Das heißt wenn als Input zum Beispiel eine ganze Tabelle mit Meßwerten zu Verfügung steht ist es möglich daraus zusätzlich oder ausschließlich repräsentative Werte wie Maximalwerte, Mittelwert, die Summe oder sonstige beliebige aus den Meßwerten generierbare Daten. Das bedeutet aber gleichzeitig auch, dass bei einem etwaigen Update der Inputdaten mit einem neuerlichen Übersetzen des Dokuments diese generierten Daten im Output ebenfalls automatisch mit upgedatet werden. Implementiert ist dies in dem Framework in folgender Weise, dass aufgrund des Designs sämtliche Inputdaten der einzelen \ac{ac:Xml}-Elemente im zur Datenspeicherung vorgesehenen \texttt{DataObject} (siehe \ref{subsec:VerwaltungVonInputdaten}, S. \pageref{subsec:VerwaltungVonInputdaten}) gespeichert werden können. Es können somit also auch ganze Tabellen oder Listen von Inputdaten dort gesammelt abgelegt werden und am Ende dieser können dann daraus die benötigten Daten, wobei dies beginnend von Extremwerten, Mittelwerten oder Summen bis hin zu ganzen statistischen Berechnungen oder Verteilungen oder beliebeige andere komplizierte Berechnungen sein können, akkumuliert und entsprechend in den Output eingefügt werden. Als einfaches Beispiel für diese Funktionalität wurde eine Liste implementiert, aus deren Daten dann wahlweise der Mittelwert oder die Summe berechnet werden und abschließend jeweils der Liste angefügt werden. \section{Lebenslauf - 2 verschiedene Zielformate} Ziel dieses auf den ersten Blick relativ einfachen Anwendungsbeispiel ist es einen Lebenslauf zu erstellen und zu übersetzen. Dazu wurde auch ein eigenes Schema entworfen, dass das Eingabeformat desselben beschreibt. Es besteht aus einem ersten Teil welcher die gesamten persönlichen Daten wie Name, Geburtsdaten, Adresse, Telefon und dergleichen enthält und anschließend einer Reihe von Listen zu den einzelnen Themen wie zum Beispiel Schulbildung, beruflicher Werdegang, weitere Qualifikationen und ähnlichen mehr. Außerdem sind noch als Attribute eine Bezeichnung des Lebenslauf und eine Sprachauswahl vorgesehen. Dieser Aufbau für das Eingabeformat des Lebenslauf wurde dadurch gewonnen, da als erstes Zielformat {\LaTeX } gewählt wurde in Zusammenspiel mit einem speziellen \ac{ac:Cv} Style. Die Übersetzung des Lebenslauf nach {\LaTeX } wurde auch speziell auf die Verwendung dieses Styles abgestimmt. Der Lebenslauf soll nun aber auch noch in andere Zielformate (z.B. \ac{ac:Html}) übersetzt werden können. Dazu kann der Großteil der Transitionen für die Übersetzung nach \LaTeX wiederverwendet werden und nur jene die effektiv den Output formatieren, welche jedoch eine geringere Anzahl darstellen, entsprechend adaptiert werden. Es können also wenn einmal die Übersetzung in ein bestimmtes Format vorhanden ist mit relativ geringem Aufwand Übersetzungen in andere Formate hinzugefügt werden. \section{Diagramme} In Geschäftsberichten, Jahresberichten, Marktanalysen, Erhebungen und noch vielen anderen Dokumenten ähnlicher Art ist es erforderlich verschiedenste Diagramme (wie z.B. Kurvendiagramme, Tortendiagramme, Blockdiagramme, ...) ins gewünschte Enddokument einzufügen. Das heißt man hat eine Reihe von Daten als Ausgangsbasis aus welchen man dann ein Diagramm beliebiger Art erstellen muß um dieses anschließend in das Dokument einzubinden. Bei diesem Framework gibt es nun dahingehend eine wesetliche Erleichterung, dass es nur notwendig ist in das Sourcedokument die gesammelten Daten für das Diagramm einzufügen, die Art des Diagramms anzugeben, welches gewünscht wird und die dafür außer den Daten noch notwendigen Angaben, und beim Übesetzen in das gewünschte Zielformat wird dann automatisch das erforderliche Diagramm erstellt und in das Enddokument eingebunden. Diese komfortable Vorgehensweise konnte gewonnen werden durch das Einbinden des \texttt{Chart2D}-Packages (FIXXME: Referenz sourceforge.net/projects/chart2d) mit welchen auf einfach Weise aus einer Reihe von Daten verschiedene Arten von Diagrammen erstellt werden können. Solche vom \texttt{Chart2D}-Package erstellten Graphiken werden dann in Files gespeichert und diese werden dann in den Output eingebunden. Der Dateninput kann also ähnliche Form wie folgt haben: \begin{verbatim} <chart> <title>Quartalsumsätze 2001</title> <list chart="pie"> <title>Quartalsumsätze</title> <item caption="1. Quartal">127</item> <item caption="2. Quartal">158</item> <item caption="3. Quartal">113</item> <item caption="4. Quartal">147</item> </list> </chart> \end{verbatim} Und dementsprechend wird dann folgene Graphik in das Enddokument eingebunden: \image[1.0]{images/Quartalsumsätze}{}{Beispiel: generiertes Tortendiagramm}{fig:PieChart} \section{Apache Servlet} \chapter{Zusammenfassung und Diskussion} nicht umgesetzte urds \section{Zusammenfassung und Diskussion} bla \section{Ausblick} bla \end{document} Index: Seminarbericht.gdf =================================================================== RCS file: /cvsroot/xpg-xml/doc/Seminarbericht.gdf,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Seminarbericht.gdf 18 May 2002 22:07:27 -0000 1.1 --- Seminarbericht.gdf 19 May 2002 18:45:27 -0000 1.2 *************** *** 258,261 **** --- 258,264 ---- %------------------------------------------------------------ + @entry{ac:Uri, URI, Uniform Resource Identifier} + + %------------------------------------------------------------ @entry{ac:Url, URL, Uniform Resource Locator} see also the glossary entry for \gls{gloss:Url} Index: Seminarbericht.tex =================================================================== RCS file: /cvsroot/xpg-xml/doc/Seminarbericht.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Seminarbericht.tex 19 May 2002 11:42:19 -0000 1.2 --- Seminarbericht.tex 19 May 2002 18:45:27 -0000 1.3 *************** *** 51,61 **** \maketitle ! \section{Abstract} ! Jeder der schon einmal ein Dokument verfasst hat steht früher oder später vor der Aufgabe dieses auch anderen Personen zugänglich zu machen. Meist ist allerdings der Inhalt wertvoller als das Aussehen des Dokumentes. Vor allem bei Wiederverwendung des enthaltenen Wissens bzw. auch nur Teilen davon, steht ! man vor dem grossen Problem der verschiedenen Dokumentformate, die von den unterschiedlichen Programmen, die zur Erstellung des Dokuments verwendet [...1085 lines suppressed...] erniedrigt) und entsprechend dieser dann der entsprechende Bezeichner in der --- 1885,1889 ---- enthaltenen Elemente ins Zielformat übersetzt. Die \texttt{<title>} Elemente enthalten die überschriften der einzelnen (Unter-)Kapitel. Für die ! \texttt{<section>} Elemente wir die jeweilige Verschachtelungstiefe akkumuliert (d.h. bei einen Starttag um eins erhöht und beim Endtag wieder um eins erniedrigt) und entsprechend dieser dann der entsprechende Bezeichner in der *************** *** 1884,1888 **** Zu obigem Beispiel kann nun die dazugehörige Dokumentenhierarchie in ! \ac{ac:Latex} folgendermaßen aussehen: \begin{verbatim} --- 1891,1895 ---- Zu obigem Beispiel kann nun die dazugehörige Dokumentenhierarchie in ! \LaTeX\ folgendermaßen aussehen: \begin{verbatim} |