XMLidP2000

Sitemap

Sitemap

1 Einführung
1.1 Warum mehr weniger ist
1.2 Warum mehr mehr ist
1.3 Wohin die Reise geht
2 Was sind Dokumente?
2.1 Eine kurze Geschichte der Textverarbeitung
2.2 Bestandteile eines Dokumentes
2.3 Die neue, alte Idee: Strukturorientiert schreiben
2.4 Die Entwicklung des Hypertextes
2.5 Textformate im Web
2.6 Das SGML-Konzept: Generic Markup
2.7 Dokumente versus Daten
3 XML im Web
3.1 XML bei der Verwaltung von Websites
3.2 Clientseitige XML-Interpretation
3.2.1 XML mit CSS
3.2.2 XML mit XSL(T)
3.3 XML auf dem Server
3.4 Linking-Möglichkeiten von XML
3.5 XML als Datenaustauschformat
4 XML Quick Start
4.1 Dokumenttyp-Definition (DTD) und Instanzen
4.2 Verarbeitung der Dokumente
4.2.1 Beispiel: Verarbeitung mit Cost/TCL
4.2.2 Beispiel: Verarbeitung mit XSLT
4.2.3 Beispiel: XML/XSLT im Internet Explorer
4.2.4 Fazit
5 XML-DTDs: Die verständliche Beschreibung
5.1 Ein Wort zur Notation
5.2 Dokumente
5.3 Elemente
5.4 Zeichen, Namen und Zeichendaten
5.5 Kommentare
5.6 Processing Instructions
5.7 Wo bleibt Multimedia?
5.8 Dokumenttyp-Definition (DTD)
5.8.1 Elementtyp-Deklaration
5.8.2 Attributlisten-Deklaration
5.8.3 Möglichkeiten, die DTD zu gestalten und zu gliedern
5.8.4 Notation-Deklaration
6 Namensräume in XML
7 XPath: Adressierung von XML-Dokumentteilen
7.1 Zu Grunde liegendes Datenmodell
7.2 Zugriff auf den Datenbaum
7.3 Hilfe von Operatoren
7.4 Kernfunktionen für den Datenzugriff
8 XML: Linking
8.1 Notwendige Begriffe
8.2 XLink: einfache und erweiterte Links
8.2.1 Einfache Verweise
8.2.2 Erweiterte Links
8.2.3 XLink in der Praxis
8.3 XPointer: Verweise in Dokumente hinein
8.3.1 XPath-Erweiterungen in XPointer
9 Überblick über Stylesheet-Sprachen
9.1 Cascading Style Sheets
9.1.1 Wertzuweisungen
9.1.2 Formatierungsmodell
9.1.3 CSS und XML
9.1.4 Ein Beispiel: XML im Mozilla
9.2 Document Style Semantics and Specification Language
9.2.1 Flow Objects
9.2.2 Verarbeitungs-Modus
9.2.3 DSSSL praktisch
9.2.4 Langer Marsch von DSSSL nach HTML
9.3 Extensible Stylesheet Language (XSLT und XSL)
9.3.1 Verhältnis von XSLT zu XSL
9.3.2 Formatierung mit XSL
10 XSL-Transformationen
10.1 Grundsätzliches über Templates
10.2 Ergänzungen zum Datenmodell von XPath
10.3 Struktur von XSLT-Stylesheets
10.4 Den Ergebnisbaum erzeugen
10.4.1 Diverse Basiselemente
10.4.2 Formatierte Nummerierung
10.4.3 Schleifen und bedingte Verarbeitung
10.4.4 Sortieren
10.4.5 Variable und Parameter
10.4.6 Zusätzliche Funktionen
10.4.7 XSLT-Erweiterungen
10.4.8 message, output
11 XSLT in Web-Anwendungen
11.1 XSLT im Internet Explorer
11.2 Linklisten erzeugen
11.3 Details einer Literaturgeschichte
11.3.1 Sortierte Überblicksseiten
11.3.2 Kalender: einzelne Tage ausgeben
12 XML-Editoren
12.1 Übersicht
12.1.1 Emacs + PSGML (mit XML-Unterstützung)
12.1.2 XML Notepad
12.1.3 XML Spy
12.1.4 XMetal
12.1.5 Epic
12.1.6 MarkupKit (für MS Word)
12.1.7 WordPerfect Office2000
12.2 Emacs und PSGML (mit XML-Unterstützung)
12.3 XML-Notepad
12.4 XML Spy
12.5 XMetal
12.6 Epic
12.7 MarkupKit (für MS Word)
12.8 WordPerfect Office2000
12.9 Fazit
13 Entwicklung einer DTD
13.1 Auswahl einer Mehrzweck-DTD
13.2 Entwurf einer DTD
13.2.1 Dokumentanalyse
13.2.2 Tipps und Tricks
13.3 Instanzen ohne DTD
14 Herstellung dieses Buches
14.1 Zielsetzung und Randbedingungen
14.2 Definition der DTD
14.2.1 Schritt 1: Die Grobstruktur
14.2.2 Schritt 2: Elemente auf Zeichenebene
14.2.3 Schritt 3: Die Details
14.3 Formatieren des Manuskriptes
14.3.1 Konvertierung in HTML
14.3.2 Aufbereitung für den Ausdruck
14.4 Erfahrungen mit der zweiten Auflage
15 Anwendungsbeispiel Literatur
15.1 Vorüberlegungen
15.2 En détail: die Autoren in der DTD
15.3 Wie die Daten ins Web gelangen
15.3.1 Inhaltsverzeichnis generieren
15.3.2 Ausgabe der Autorendaten
15.4 Vollständige Listings
15.4.1 DTD für die Literaturgeschichte
15.4.2 DSSSL-Listing: Inhaltsverzeichnis
15.4.3 DSSSL-Listing: Ausgabe eines einzelnen Autors
15.4.4 Perl-Code für Ausgabe einzelner Autoren
16 Verteilte Softwareverwaltung mit XML
16.1 Aufgabenbeschreibung
16.2 XML als Datenbasis
16.3 Bilden von DTD-Hierarchien
16.4 Zusammentragen von verteilten XML-Fragmenten
16.5 Fazit
16.6 Stylesheet zur Transformation in HTML
17 E-Commerce mit XML
17.1 B2B-E-Commerce
17.1.1 Die Rolle von XML
17.1.2 Technische Aspekte
17.2 BMEcat
17.3 Electronic Business XML (ebXML)
17.3.1 Arbeitsgruppen
17.3.2 Zeitplan des Projekts
17.4 XML und EDIFACT
18 XML und Apache
18.1 XML-Transformation per CGI
18.1.1 Konfiguration des Servers
18.1.2 CGI-Skript: xmlhandler.cgi
18.1.3 Beispiel: von HTML nach HTML mit DSSSL oder XSLT
18.2 Cocoon
18.2.1 Extensible Server Pages (XSP)
18.2.2 Beispiel: Formatierung in PDF mit XSL
18.2.3 Beispiel: Simuliertes XLink mit Dynamic HTML/JavaScript
18.2.4 Installation
19 XHTML: Neues HTML 4 — erweiterbar
19.1 Status quo: HTML neu definiert
19.2 Modulare Zukunft
20 Transformation von XML in WML und HTML
20.1 Erzeugen der WML-Dateien
20.2 Erzeugen der HTML-Dateien
21 Ausblick
21.1 XML Schema
21.2 Programmierung mit XML-Daten
21.3 XML und Java
21.4 Resource Description Framework
21.5 Die Zukunft
A Extensible Markup Language (XML) 1.0
A.1 Einleitung
A.1.1 Herkunft und Ziele
A.1.2 Terminologie
A.2 Dokumente
A.2.1 Wohlgeformte XML-Dokumente
A.2.2 Zeichen
A.2.3 Allgemeine syntaktische Konstrukte
A.2.4 Zeichendaten und Markup
A.2.5 Kommentare
A.2.6 Processing Instructions
A.2.7 CDATA-Abschnitte
A.2.8 Prolog und Dokumenttyp-Deklaration
A.2.9 Standalone-Dokumentdeklaration
A.2.10 Behandlung von Leerraum
A.2.11 Behandlung des Zeilenendes
A.2.12 Identifikation der Sprache
A.3 Logische Strukturen
A.3.1 Start-Tags, End-Tags und Leeres-Element-Tags
A.3.2 Elementtyp-Deklarationen
A.3.3 Attributlisten-Deklaration
A.3.4 Bedingte Abschnitte
A.4 Physikalische Strukturen
A.4.1 Zeichen- und Entity-Referenzen
A.4.2 Entity-Deklarationen
A.4.3 Analysierte Entities
A.4.4 Behandlung von Entities und Referenzen durch einen XML-Prozessor
A.4.5 Konstruktion des Ersetzungstextes von internen Entities
A.4.6 Vordefinierte Entities
A.4.7 Notation-Deklarationen
A.4.8 Dokument-Entity
A.5 Konformität
A.5.1 Validierende und nicht-validierende Prozessoren
A.5.2 Benutzen von XML-Prozessoren
A.6 Notation
A.7 Anhang A: Referenzen
A.7.1 Normative Referenzen
A.7.2 Weitere Referenzen
A.8 Anhang B: Zeichenklassen
A.9 Anhang C: XML und SGML (nicht normativ)
A.10 Anhang D: Expansion von Entity- und Zeichenreferenzen (nicht normativ)
A.11 Anhang E: Deterministische Inhaltsmodelle (nicht normativ)
A.12 Anhang F: Automatische Erkennung von Zeichenkodierungen (nicht normativ)
A.13 Anhang G: XML-Arbeitsgruppe des W3C (nicht normativ)
B Verknüpfen von Style Sheets mit XML-Dokumenten Version 1.0
B.1 Die xml-stylesheet-Processing-Instruction
B.2 Anhang A: Referenzen
B.3 Anhang B: Begründung
C Verhältnis von XML zu SGML und HTML
C.1 XML und SGML
C.2 XML und HTML
D Übersichten
D.1 Cascading Style Sheets
D.1.1 CSS-Eigenschaften und -Werte
D.1.2 CSS-Muster
D.2 DSSSL: Flow Objects
D.3 Syntax der XSLT-Elemente
D.4 DTD-Fragment für XSLT-Stylesheets (nicht normativ)
D.5 Relevante Spezifikationen und Organisationen
D.5.1 International Organization for Standardization
D.5.2 World Wide Web Consortium
D.5.3 Organization for the Advancement of Structured Information Standards
D.5.4 Internet Society und Internet Engineering Task Force
D.5.5 ISO-639-Sprachcodes
D.5.6 ISO-3166-Ländercodes
D.5.7 Zeichensatz ISO-Latin-1
D.5.8 Sonderzeichen
D.6 XML-1.0-Regeln

15.3.2 Ausgabe der Autorendaten

Für eine solche Anwendung ist ein Inhaltsverzeichnis nur der allererste Schritt, danach beginnt die eigentliche Arbeit. Als Beispiel für weitere Sichten auf die Daten sei hier eine herausgegriffen: die Ausgabe von Daten eines einzelnen Autors. Für diesen Schritt sprechen mehrere Gründe. Obwohl dieses Stylesheet schon umfangreicher ist als das für das Inhaltsverzeichnis, hält es sich noch in darstellbaren Grenzen. Außerdem ist es damit ansatzweise möglich zu zeigen, wie man mit Hilfe der Eigenschaften von Scheme die Ausgabe verändern kann. Um auch darauf hinzuweisen, was komplexer ist und deshalb hier nicht vorkommt, seien zwei weitere mögliche Style Sheets respektive Sichten wenigstens erwähnt. Das Element what enthält das Attribut cat, das beispielsweise den Wert nobel haben kann. Dieser Attributwert soll es erleichtern, die Nobelpreisträger aus dem Dokument zu filtern. Für den Fall, dass man sie zeitlich sortiert ausgeben will, ist eine Sortierfunktion erforderlich, die die Damen und Herren in die richtige Reihenfolge bringt. Gleiches gilt für die Ausgabe aller Werke — unabhängig vom Autor — in der historischen Abfolge und für Jahresausgaben (hinsichtlich der Monate und Tage).

Umfangreicher ist das Style Sheet für einzelne Autoren schon deshalb, weil man für mehr Elemente festlegen muss, ob und was zur Ausgabe kommen soll. Das gilt nicht für lithist, weil das außer Überschrift und Nachsatz lediglich die Angabe enthalten muss, dass die passenden Kindelemente (author) zu verarbeiten sind. Dort und — hierarchisch gesehen — darunter stehen die Anweisungen, wie mit den einzelnen Elementen zu verfahren ist. Da in diesem Style Sheet fast alles ausgegeben wird, eignet sich die Default-Anweisung (empty-sosofo) hier nicht. Wenn überhaupt eine Default-Regel für Elemente, deren Verarbeitung nicht ausdrücklich angegeben ist, dann eine, die besagt: Verarbeite deine Kinder. Das wäre

(default (process-children))
          

Im Element author selbst wird eine Tabelle aufgebaut, die — unterbrochen von einer horizontalen Linie — die Elemente vita, event,work und comment aufbereitet. Elemente wie born und died eröffnen jeweils eine Zeile für das Geburts- und Sterbedatum. Andere Elemente verfahren auf dieselbe Weise für ihre Kinder. Die entscheidende Funktion innerhalb von author heißt if, denn sie bewirkt, dass nur die Daten des Autors ausgegeben werden, die der gestellten Bedingung genügen:

(if (string=? thisAuthor (attribute-string "ID" (current-node)))
; ---- (Anweisung) (else-Anweisung))
          

Nur wenn der Inhalt der Variablen thisAuthor dem Inhalt des Attributs id gleicht, kommt es zur Ausgabe der Daten. Ansonsten liefert author ein (empty-sosofo) zurück, mit dem Erfolg, dass nichts erfolgtFussnoteDen Fall, dass kein Autor gefunden wird, dessen id mit der Variablen übereinstimmt, kann man getrost ausschließen, denn die Auswahl an Autoren bestimmt ja diejenigen, die im Formular auftauchen .... Leider ist es nicht möglich, eine solche Variable an Jade zu übergeben. Deshalb musste Perl herhalten. Das fertige Stylesheet und eine auf Grund der getroffenen Auswahl generierte define-Anweisung schreibt ein CGI-Skript in ein weiteres (temporäres) Style Sheet, das Jade von Perl aus beim Aufruf übergeben wird. Die Variablendeklaration sieht so aus:

(define thisAuthor "MANNT")

Das Perl-Listing findet sich im Anhang dieses Kapitels; eleganter wäre es, zugegebenermaßen, käme man ohne solche externen Programme aus und könnte Jade die Autorenkennung als Parameter übergeben.

Ausgabe der Daten zu Thomas Mann

Abbildung 57: Ausgabe der Daten zu Thomas Mann

Noch ein paar Worte zum Style Sheet selbst. Es enthält direkt nach der default-Anweisung ein paar Funktionen, die zunächst nichts mit konkreten Elementen zu tun haben. Zwei dieser Funktionen definieren lediglich Listen: erst die Monate in zwei Sprachen, dann die Landesbezeichnungen. Dass letztere Liste außerdem die Länderkürzel enthält, liegt daran, dass diese für den Abgleich in der Funktion getcountry erforderlich sind, während die richtigen Monate sich automatisch über die Zahlen ergeben.

Beispiel

Ein Blick auf eine der beiden Funktionen soll an dieser Stelle nur zeigen, dass man mit DSSSL respektive Scheme Dokumente bearbeiten kann, bevor sie zu HTML-Daten mutieren.

(define (getmonth mo li lang)
  (if (=  mo 1)
      (if (equal? lang "de")
          (car (car li))
	  (car (cdr (car li))))
      (getmonth (- mo 1) (cdr li) lang)))

(define monate (list (list "Januar" "January")
		(list "Februar" "February")
; ----- weitere Monate
		(list "Dezember" "December")))

; ----- Aufruf im Element month mit
(literal (getmonth 
    (string->number 
        (data (current-node))) 
               monate "de"))

Auffällig für diejenigen, die noch nicht mit Scheme oder einem anderen Lisp-Dialekt gearbeitet haben, sind die in getmonth verwendeten Funktionen car und cdr, die hier auch noch in Kombination auftreten (sie waren auch schon Bestandteil von copy-attributes im vorigen Kapitel). Hinter diesen mnemonisch perfekten AkronymenFussnotecar hat tatsächlich nichts mit Autos zu tun, vielmehr ist es die Abkürzung von Contents of Address Register. Und cdr heißt Contents of Decrement Register. stecken zwei der wichtigen Lisp-Grundfunktionen zur Bearbeitung von Listen. car extrahiert aus einem Paar die erste Komponente (auch dann, wenn es sich wiederum um eine Liste handelt), cdr hat den Rest des ursprünglichen Paares zum Ergebnis.

getmonth definiert zwei mögliche Aktionen: Falls der Monat die Zahl 1 liefert, muss die Funktion das erste Glied der ersten Liste (Januar) ausgeben — vorausgesetzt, als Sprache ist Deutsch vorgegeben (über den Parameter de beziehungsweise lang in der Funktionsübergabe). In allen anderen Fällen ruft sich getmonth rekursiv auf, und zwar mit der restlichen (um den ersten Monat verkürzten) Liste.

Bei einem Wert von mo = 3 bedeutet das nach dem ersten (erfolglosen) Durchlauf einen Aufruf von getmonth mit mo = 2 und der um die Januar-Liste verkürzten Gesamtliste der Monate. Auch diesmal ist mo ungleich 1, so dass die Prozedur, diesmal mit mo = 1, noch einmal aufgerufen werden muss — jeweils mit einer um die erste Monatsliste verkürzten Gesamtmonatsliste.

Rekursion kann man ein Grundprinzip von Lisp-Sprachen nennen. Programme folgen oft zwei einfachen Regeln:

  1. Abbruchbedingung festlegen
  2. Was geschieht, wenn die Abbruchbedingung nicht erfüllt ist?

Im Beispiel liest sich das so: erstes Glied der Liste heraussuchen.

(list "Januar" "January")

Bedingung erfüllt? Dann: Abbruch/Ausgabe. Wenn der Monat als Zahl nicht erreicht ist, nimm Dir den Rest der Liste vorFussnoteDas war wahrscheinlich der kürzeste und meistverkürzte Lisp-Kurs weit und breit..

So weit der Einbau von Funktionen. Natürlich wäre mehr möglich. Aber zurück zu den Elementen: Bei der Ausgabe der Autorenelemente sieht einiges anders aus als beim Inhaltsverzeichnis, schließlich sollen hier ja konkrete Daten ausgegeben werden (anstatt nur der Name). Innerhalb des Elements author muss also wesentlich mehr geschehen, als im Inhaltsverzeichnis beschrieben:

(element author
    (if (string=? thisAuthor 
                  (attribute-string "ID" (current-node)))
        (make sequence
           (process-matching-children 'name)
           (make element gi: "TABLE" 
                 attributes: (cons (list "border" "0")
                         (cons (list "width" "100%")
                          (cons (list "cellspacing" "0")
                           (cons (list "cellpadding" "2")
                        '()))))
           (make element gi: "CAPTION"
              (make element gi: "H3"
                (literal "Leben und Werk"))
              (make element gi: "H3"
                    attributes: (cons (list "class" "eng")
                               '())
                (literal "Life and Works")))
              (process-matching-children 'vita)
              (process-matching-children 'event)
              (process-matching-children 'work)
              (process-matching-children 'comment)))
        (empty-sosofo)))

Falls das Attribut id mit der Variablen thisAuthor übereinstimmtFussnoteLeider ist hier auf Großschreibung zu achten. Jade nimmt Kleinschreibung übel, das heißt: Auch wenn die ids klein daherkommen, macht Jade sie zu Versalien., wird mit make sequence die Ausgabe eingeleitet: eine Tabelle mit Überschriften (caption mit zwei h3) sowie die Kindelemente (process-matching-children). Wenn Variable und Kennung nicht übereinstimmen, gilt das (empty-sosofo)FussnoteDas empty-sosofo steht hier nur der Form halber, denn da in den Optionen nur vorhandene Autor(inn)en aufgenommen sind, kann es zu diesem Fall nicht kommen., das heißt, es geschieht nichts.

Bei der Verarbeitung von vita beziehungsweise den in der Hierarchie noch tiefer angesiedelten Elementen born und died kommt unter anderem die oben vorgestellte Funktion getmonth zum Einsatz, die aus den Monatsziffern Wörter macht. Gerade in diesem Fall hat eine solche Funktion ihren Sinn, denn an anderer Stelle sollen die Monate als Zahlen vergleichbar sein, damit man einen Kalender etc. umsetzen kann.FussnoteBei den Ländernamen (siehe das gesamte Listing am Ende des Kapitels) ergibt sich der Sinn erst bei mehreren Sprachen, denn im XML-Quelltext geht es, wie die Entwickler deutlich gemacht haben, nicht um Knappheit (terseness). Man könnte also mit den Langbegriffen wuchern.

Innerhalb der einzelnen Elemente sind nicht viele Besonderheiten versteckt; die meisten geben Teile einer Tabelle aus, etwa:

; ---------------------- gestorben?
(element died
  (make element gi: "TR"
    (make element gi: "TH"
         attributes: (cons (list "class" "when")
                      '()) (process-matching-children 'year))
    (make element gi: "TD"
           attributes: (cons (list "class" "life")
                      '())        
        (literal "gestorben/died: ")
        (process-matching-children 'day) 
        (process-matching-children 'month)
           (make element gi: "SPAN"
                  attributes: (cons (list "class" "life")
                              '())
        (process-matching-children 'where)))))

; ---------------------- wann geboren/gestorben?

(element month
      (make sequence
         (literal (getmonth 
                     (string->number 
                         (data (current-node))) 
                                monate "de"))
         (literal " ")))

(element day
      (make sequence
              (process-children)
   (literal ". ")))

Geburts- und Sterbedatum lassen sich analog ausgeben. Der einzige Grund dafür, beide Elemente aufzuführen, ist, dass unterschiedliche Strings wie gestorben/died: respektive geboren/born: zu berücksichtigen sind. Schließlich muss bei Geburts- und Todestagen dem eigentlichen Inhalt des Elements (der Zahl) ein . folgen, damit der Monat nicht direkt am Tag klebt.

In fast allen konkreten Fällen (das oben stehende Element day ist eine der Ausnahmen, weil es sich um ein Blatt, ein Endelement, handelt) sorgt das Stylesheet dafür, dass Teile einer Tabelle aufgebaut werden. Für Geburts- oder Todestage gibt es etwa zwei Zeilen (TR), in denen zunächst das Jahr (TH) und anschließend Monat, Tag und Ort samt Staat (im zweiten TD) ausgegeben werden. Das Jahr taucht hier nicht auf, weil es nicht bearbeitet werden muss — und dafür reicht die Default-Regel process-children.

Manche Leser mögen sich fragen: Ist das alles? Jein. Ja hier, nein ansonsten. Über einzelne Autor(inn)en hinausgehende Informationen lassen sich, wie schon erwähnt, ebenfalls generieren. Allerdings erfordern sowohl Übersichten über Personen als auch über Werke, etwa aufs Jahrhundert gerechnet, weitere Scheme-Funktionen. Zum Beispiel eine Sortier-Routine, deren Darstellung den Rahmen einer (wenn auch praxisorientierten) Einführung in XML sprengte.

Valid HTML 4.01!Valid CSS!