1: Agenda
-
Einführung
- Was ist XML?
- Was ist XSL/XSLT?
- Was ist XPath?
-
PHP 5 Extensions für XML/XSLT
- DOM
- Simplexml
- XML extension (SAX)
- XMLReader
- XMLWriter
- SOAP, XML-RPC, ...
- XSL
-
Praktisches Beispiel: xphp-slides
- PHP XSLT Tricks
- Möglichkeiten von XSLT als Transformations (Template) Sprache
- Warum es sinnvoll ist Standards zu verwenden
2: Fragen vorab:
- Wer hat schon mit XML gearbeitet?
- Wer hat schon mit XSLT gearbeitet?
- Wer arbeitet mit XML und PHP5?
- Wer arbeitet mit XML und PHP4?
Wer mit PHP4 und XML arbeitet sollte auf PHP5 umsteigen, es lohnt sich!
3: Was ist XML
XML = eXtensible Markup Language
Die vom W3C herausgegebene XML-Spezifikation definiert eine Metasprache, auf deren Basis durch strukturelle und inhaltliche Einschränkungen, die Grammatik, anwendungsspezifische Sprachen definiert werden können.
Diese Einschränkungen werden durch Schemasprachen wie DTD oder XML-Schema ausgedrückt.
Beispiele für XML-Sprachen sind: RSS, MathML, GraphML, XHTML, Scalable Vector Graphics, aber auch XML-Schema und XSLT.
- XML ist eine vereinfachte Teilmenge von SGML
- XML ist ein W3C Standard.
- XML, ist eine Auszeichnungssprache zur Darstellung hierarchisch strukturierter Daten in Form von Textdateien.
- XML ist plattfrom unabhängig.
- XML kann mit den meisten Programiersprachen verarbeitet werden
- XML bietet Unicode Support
4: Regeln für XML-Dokumente
Man unterscheidet "wohlgeformte" und "valide" bzw. "gültige" XML-Dokumente.
Regeln für wohlgeformte XML-Dokumente:- Das Dokument besitzt genau ein Wurzelelement.
- Alle Elemente besitzen ein Anfangs- und ein End-Tag.
- Elemente müssen korrekt verschachtelt sein
- Ein Element darf nicht mehrere Attribute mit dem gleichen Namen besitzen.
- Das Dokument ist wohlgeformt.
- Das Dokument enthält den Verweis auf eine Grammatik (z.B. DTD oder XML-Schema)
- Das Dokument hält das in der Grammatik beschriebene Format ein.
5: XML Beispiel
<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
<book name="Example-Book">
<title>This is an Example-Book</title>
<chapter id="1">
<title>Title from Chapter 1</title>
<para>Text in chapter 1</para>
</chapter>
<chapter id="2">
<title>Title from Chapter 2</title>
<para>Text in chapter 2</para>
</chapter>
</book>
6: Was ist XSL/XSLT
XSL = eXtensible Stylesheet Language
XSL ist eine Familie von Sprachen zur Erzeugung von Layouts für
XML-Dokumente.
Zu XSL gehören: XSLT (Transformation),
XSL-FO (Formatierung) und indirekt auch XPath für die
Adressierung von Teilbäumen.
XSLT = XSL Transformations
XSLT ist eine Programmiersprache, die es ermöglicht Elemente
einer XML-basierten Sprache in eine andere XML-gerechte Sprachen
zu transformieren.
Man spricht auch von der Transformation aus einem Quellbaum in
einen Ergebnisbaum.
XSLT-Programme, sogenannte XSLT-Stylesheets, sind dabei ebenfalls nach den Regeln des XML-Standards aufgebaut (Namespace für XSLT).
XSLT-Prozessoren lesen XSLT-Stylesheets ein und transformieren ein oder mehrere XML-Dokumente nach den Stylesheet-Regeln in das gewünschte Ausgabeformat.
Wikipedia: XSL TransformationWikipedia: Extensible Stylesheet Language
7: Was ist XPath
XPath = XML Path Language
- XPath ist ein W3C Standard.
- XPath betrachtet ein XML-Dokument als Baum.
- XPath ist eine Anfragesprache, um Teile eines XML-Dokuments zu adressieren.
- Xpath ist plattfromunabhängig.
- XPath wird von vielen Sprachen unterstützt.
- XPath ist wichtig für XSLT.
8: XPath Beispiele
- / selektiert das Wurzel-Element
- /book selektiert das Wurzel-Element book
- /book/chapter selektiert alle chapter-Elemente des Wurzel-Elements book
- /book/chapter[1] selektiert das erste chapter-Element im Wurzel-Element book
- //title selektiert alle title-Elemente auf allen Ebenen
- //chapter[@name="Chapter-2"]/title[1] selektiert das erste title-Element des chapter-Elements dessen Attribut name den Wert "Chapter-2" hat.
- ./text() selektiert alle Text-Elemente des aktuellen Elements
- attribute::* selektiert alle Attribute des aktuellen Elements
9: PHP5 Extensions für XML/XSLT
Alle PHP5 XML-Extensions basieren auf der libxml2.
Die PHP5 Extensions für XML/XSLT können aufgrund ihrer Funktionalität und Arbeitweise in 4 Kategorien unterteilt werden:
- Document Object Model (DOM)
- DOM Ersetzt DOMXML in PHP4
- SimpleXML PHP5 only
- Simple API for XML (SAX)
- XML extension PHP4 und PHP5
- XMLReader PHP5 only
- XMLWriter PHP5 only
- Web Services
- XML-RPC PHP4 und PHP5
- SOAP PHP5 only
- XML Transformation
- XSL Ersetzt XSLT in PHP4
10: SimpleXML
Sterling Hughes:
"XML is the solution to all your problems; SimpleXML ensures it
isn't the root of your problems!"
- Per Default in PHP5 verfügbar
- Sehr schnell
- Sehr einfach
- Objektorientiert
- Unterstützt XPath
- Ermöglicht einfache Schreibzugriffe
- Interoperabel mit DOM
11: SimpleXML - Beispiel
<?php
# Laden und parsen der XML-Datei
$xml = simplexml_load_file(dirname(__FILE__) . '/book.xml');
# Ausgeben der Daten
echo "<h1>Buchtitel: " . $xml['name'] . "</h1>\n";
# Die chapter und dessen Kinder ausgeben
foreach ($xml->chapter as $chapter) {
echo "<h2>Kapitel: " . $chapter->title . "</h2>\n";
echo "<p>" . $chapter->para . "</p>\n";
}
?>
<h1>Buchtitel: Example-Book</h1> <h2>Kapitel: Title from Chapter 1</h2> <p>Text in chapter 1</p> <h2>Kapitel: Title from Chapter 2</h2> <p>Text in chapter 2</p>
12: SimpleXML und XPath - Beispiel
<?php
# Laden und parsen der XML-Datei
$xml = simplexml_load_file(dirname(__FILE__) . '/book.xml');
# Den Title des ersten Kapitels ausgeben
echo "<p>" . array_shift($xml->xpath("//chapter[1]/title")) . "</p>\n";
# Den chapter Knoten mit der id "2"
print_r($xml->xpath("//chapter[@id=2]"));
?>
<p>Title from Chapter 1</p>
Array
(
[0] => SimpleXMLElement Object
(
[@attributes] => Array
(
[id] => 2
)
[title] => Title from Chapter 2
[para] => Text in chapter 2
)
)
13: SimpleXML hat seine Grenzen - Beispiel
SimpleXML ist für einfache Aufgaben und Strukturen gemacht, hat aber klare Grenzen wenn die Daten-Strukturen komplizierter werden.
Beispiel: verschachtelte Tags
<?php
# XML mit verschachtelten Tags
$xml_string = '<book><chapter>Irgendein <strong>fetter</strong> Text</chapter></book>';
$xml = simplexml_load_string($xml_string);
echo $xml->chapter . "\n";
echo $xml->chapter->strong . "\n";
?>
Irgendein Text fetter
Wenn SimpleXML nicht mehr reicht -> DOM verwenden
14: DOM
DOM (PHP5) ist NICHT kompatibel mit DOMXML (PHP4)
Die DOM Extension in PHP5 ist komplett neu geschrieben und nutzt viele der neuen PHP5 Features (OO, SPL,...).
DOM Features:- Unterstützt DOM Level 3
- API entspricht der DOM Level 3 Spezifikation
- Unterstützt XPath
- Unterstützt Namespaces
- Unterstützt Validierung gegen DTD, XML-Schema und relaxNG
- HTML Support
- Interoperabel mit SimpleXML
15: DOM: Access by TagName - Beispiel
<?php
# DOM Objekt erstellen
$dom = new domDocument();
# Laden und parsen der XML-Datei
$dom->load(dirname(__FILE__) . '/book.xml');
# Alle Titel ausgeben -> Zugriff ueber Tag-Name
foreach ($dom->getElementsByTagName('title') as $node) {
echo $node->nodeValue . "\n";
}
?>
This is an Example-Book Title from Chapter 1 Title from Chapter 2
16: DOM: Access by ID - Beispiel
DOMDocument->getElementById() benötigt die Definition eines
Attributes als Typ "ID".
Der Attribut-Name "id" reicht nicht aus!
<?php
# DOM Objekt erstellen und Laden der XML-Datei
$dom = new domDocument();
$dom->load(dirname(__FILE__) . '/book-id.xml');
# Zugriff ueber ID benoetigt ein Attribut vom Typ ID
$node = $dom->getElementById('2');
echo trim($node->nodeValue) . "\n";
# Oder man setzt explizit welches Attribut vom Typ ID ist
$dom->documentElement->setIdAttribute('name', TRUE);
$node2 = $dom->getElementById('Example-Book');
echo trim($node2->getAttribute('name')) . "\n";
?>
Title from Chapter 2 Text in chapter 2 Example-Book
17: DOM: Dokumenten-Baum - Beispiel
<?php
$dom = new domDocument();
$dom->load(dirname(__FILE__) . '/book.xml');
show_node_childs($dom->documentElement);
// Rekursive Funktion zum Traversieren des Dokument-Baums
function show_node_childs($node) {
foreach ($node->childNodes as $child) {
if ($child->nodeType == XML_ELEMENT_NODE){
if ($id = $child->getAttribute("id")) {
echo "ID -> " . $id . "\n";
}
echo $child->nodeName . " => " . $child->nodeValue . "\n";
if ($child->hasChildNodes()) {
show_node_childs($child);
}
}
}
}
?>
title => This is an Example-Book
ID -> 1
chapter =>
Title from Chapter 1
Text in chapter 1
title => Title from Chapter 1
para => Text in chapter 1
ID -> 2
chapter =>
Title from Chapter 2
Text in chapter 2
title => Title from Chapter 2
para => Text in chapter 2
18: DOM und XPath - Beispiel
<?php
$dom = new domDocument(); // DOM Objekt erstellen
$dom->load(dirname(__FILE__) . '/book.xml'); // XML laden
$xp = new DomXPath($dom); // xPath Objekt erstellen und XML/DOM ubergeben
// Den Titel des Chapters mit der id=2
$res = $xp->query("//chapter[@id=2]/title");
echo $res->item(0)->nodeValue; // Inhalt des 1. Eintrags ausgeben
?>
Title from Chapter 2
19: DOM und SimpleXML - Beispiel
<?php
$dom = new domDocument();
$dom->load(dirname(__FILE__) . '/book.xml');
$new_item = $dom->createElement('chapter'); # Neuen chapter Knoten erstellen
$new_item->setAttribute("id", 1234); # id Attribut fuer das neue Chapter
foreach (array('title', 'para') as $name) { # title und para child einfuegen
$node = $dom->createElement($name);
$node->appendChild($dom->createTextNode($name . '::Text'));
$new_item->appendChild($node);
}
# Neuen Knoten in das Dokument einfuegen
$dom->documentElement->appendChild($new_item);
# DOM Objekt in SimplXMl importieren...
$xml = simplexml_import_dom($dom);
# ... und mit SimpleXML ausgeben
foreach ($xml->chapter as $chapter) {
echo "ID: " . $chapter['id'] . " => " . $chapter->title . "\n"
. $chapter->para . "\n\n";
}
?>
ID: 1 => Title from Chapter 1 Text in chapter 1 ID: 2 => Title from Chapter 2 Text in chapter 2 ID: 1234 => title::Text para::Text
20: DOM und HTML - Beispiel
<?php
$dom = new DomDocument();
# externes HTML-Dok laden (@ falls nicht valide)
@$dom->loadHTMLFile("http://www.php.net/");
# Mit XPath den title Text auslesen
$xp = new DomXpath($dom);
$res = $xp->query("//title/text()");
echo $res->item(0)->nodeValue;
?>
PHP: Hypertext Preprocessor
21: XML extension (SAX)
SAX = Simple API for XML
Die XML extension implementiert einen eventbasierten SAX-Parser.
Im Gegensatz zu DOM, wo immer das komplette XML Dokument als Baum in den Speicher geladen wird, liest ein SAX-Parser XML als sequentiellen Datenstrom und ruft Callback-Funktionen für die definierte Ereignisse (Events) auf.
Dadruch ist die XML extension "speicherschonend" und besonders für große XML-Dateien geeignet.
SAX-basierte Anwendungen registrieren für die verschiedenen Ereignisse Callback-Funktionen beim Parser um die XML-Daten auswerten, bzw. weiterverarbeiten zu können.
Die 3 wichtigsten Ereignisse dabei sind:
- startElement
- endElement
- characterData
SAX ist ein De-Facto-Standard und unterliegt keinem formalen Komitee oder Konsortium.
Wikipedia: SAX22: SAX-Parser - Beispiel
<?php
# Die callback Funktionen definieren
function startElement($parser, $name, $attrs) {
echo "Open: " . $name . "\n";
}
function endElement($parser, $name) {
echo "Close: " . $name . "\n";
}
function characterData($parser, $data) {
if ($data = trim($data)) {
echo "Data: " . $data . "\n";
}
}
$xml_parser = xml_parser_create(); # Parser erstellen
xml_set_element_handler($xml_parser, "startElement", "endElement"); # callback Funktionen registrieren
xml_set_character_data_handler($xml_parser, "characterData"); # callback Funktionen registrieren
$fp = fopen("book.xml", "r"); # XML-File zum Lesen öffnen
while ($data = fread($fp, 4096)) { # XML-Daten lesen und parsen
if (!xml_parse($xml_parser, $data, feof($fp))) {
die(sprintf("XML error: %s at line %d",
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser)));
}
}
xml_parser_free($xml_parser); # Parser wieder schliessen
?>
Open: BOOK Open: TITLE Data: This is an Example-Book Close: TITLE Open: CHAPTER Open: TITLE Data: Title from Chapter 1 Close: TITLE Open: PARA Data: Text in chapter 1 Close: PARA Close: CHAPTER Open: CHAPTER Open: TITLE Data: Title from Chapter 2 Close: TITLE Open: PARA Data: Text in chapter 2 Close: PARA Close: CHAPTER Close: BOOK
23: XmlReader
Genau wie ein SAX-Parser arbeitet XmlReader "speicherschonend", da nicht das gesamte Dokument auf einmal in den Speicher geladen wird.
XmlReader Features:- Cursor-basierter Parser für XML
- Seit PHP 5.1.0 standardmäßig in PHP enthalten
- Für ältere Versionen aber als PECL-Modul verfügbar
- Support für Namespaces
- Support für Validierung
- Support für Entities
- Ersatz für den SAX-Parser (?)
Im Gegensatz zum SAX-Basierten Parser müssen keine callback-Funktionen registriert werden. Die Anwendung kann anhand von Konstanten auf die verschiedenen Knoten-Typen reagieren.
Seit PHP 5.1 verwendet der XMLReader Klassenkonstanten, z.B. XMLReader::ELEMENT. Frühere Versionen verwenden globale Konstanten in Form von XMLREADER_ELEMENT.
24: XmlReader - Beispiel
<?php
$reader = new XMLReader(); # XMLReader object erstellen
$reader->open(dirname(__FILE__) . '/book.xml'); # Datenfile oeffnen
while ($reader->read()) { # Loop ueber die Elemente des Dokuments
// Anhand des Knoten-Typs unterscheiden was gemacht wird
switch ($reader->nodeType) {
case XMLReader::ELEMENT:
echo "Open: " . $reader->localName . "\n";
break;
case XMLReader::TEXT:
echo "Data: " . $reader->value . "\n";
break;
case XMLReader::END_ELEMENT:
echo "Close: " . $reader->localName . "\n";
break;
}
}
?>
Open: book Open: title Data: This is an Example-Book Close: title Open: chapter Open: title Data: Title from Chapter 1 Close: title Open: para Data: Text in chapter 1 Close: para Close: chapter Open: chapter Open: title Data: Title from Chapter 2 Close: title Open: para Data: Text in chapter 2 Close: para Close: chapter Close: book
25: XMLWriter
XMLWriter bietet eine einfache API zum Erzeugen von Datenströmen oder Dateien mit XML-Inhalten.
XMLWriter arbeitet wie XMLReader cursor-basiert.
XMLWriter Features:- Schreibt XML Streams direkt in Dateien oder in den Speicher
- Schneller und einfacher Weg um valides XML zu erzeugen
- Support für DTD Definitionen
- Support für Namespaces
- Objektorientiert oder prozedural verwendbar
- Automatische Behandlung von Sonderzeichen wie z.B. &
- Wrapper für die libxml2 xmlWriter-API
26: XMLWriter - Beispiel
<?php
$xw = New xmlWriter(); // Neues xmlWriter Objekt
$xw->openMemory(); // Oeffnen eines XML-Dokuments im Speicher
$xw->setIndent(TRUE); // sieht einfach besser aus ;-)
$xw->startDocument(); // start document
$xw->startElement("book"); // start <book>
$xw->writeElement('title', 'Titel des Test-Books'); // <title> with content
$xw->startElement("chapter"); // start <chapter>
$xw->writeAttribute("id", 1); // add attribute to example
$xw->writeElement('title', 'Titel des Test-Chapters'); // <title> with content
$xw->startElement("para"); // add node <para>
$xw->text("irgendein Text"); // add content to node <data>
$xw->endElement(); // close node <para>
$xw->endElement(); // close node <chapter>
$xw->endElement(); // close node <book>
$xw->endDocument(); // end document
echo $xw->outputMemory(); // Ausgabe des erzeugten XML
?>
<?xml version="1.0"?> <book> <title>Titel des Test-Books</title> <chapter id="1"> <title>Titel des Test-Chapters</title> <para>irgendein Text</para> </chapter> </book>
27: XML-RPC
XML-RPC = Extensible Markup Language Remote Procedure Call
XML-RPC ist eine einfache Definition für Methoden-, bzw. Funktionsaufrufe durch verteilte Systeme.
Das zugrunde liegende Protokoll zur Datenübertragung ist HTTP.
Die Darstellung der zu übertragenden Daten erfolgt in XML.
XML-RPC kann als Vorgänger von SOAP gesehen werden, ist im Gegensatz zu SOAP aber deutlich schlanker (weniger Overhead) und einfacher.
Wikipedia: XML-RPC28: XML-RPC
Vorteile:- Schlank
- Schnell
- Einfach
- Wird von vielen Programmiersprachen unterstützt (PHP, Perl, Ruby, Phyton, Java, JavaScript, C, .NET, ActionScript(Flash), uvm.)
- Nicht per Default in PHP aktiviert.
- Die Erweiterung ist noch als EXPERIMENTELL getagged, d.h. die API kann sich in zukünftigen Versionen ohne Ankündigung ändern.
- Nicht Buzzword kompatibel ;-)
29: SOAP
Die SOAP Extension von PHP5 ermöglicht es sowohl SOAP-Server, als auch SOAP-Clients zu implementieren.
Genau wie XML-RPC ist SOAP eine Definition für Methoden-, bzw. Funktionsaufrufe durch verteilte Systeme, die als Darstellung der zu übertragenden Daten XML verwendet.
Vorteile:- Die PHP API macht die Nutzung sehr einfach
- Support für (Teile) der SOAP 1.1, SOAP 1.2 und WSDL 1.1 Spezifikationen
- Voll Buzzword kompatibel ;-)
- Noch nicht in allen Bereichen komplett und stabil
- Interne Konzepte von SOAP sind (manchmal) nicht ganz einfach zu verstehen
- SOAP hat relativ großen Overhead
30: XSL Extension
Die XSL Extension basiert auf der libxslt library
XSL Features:- In PHP5 per Default aktiviert.
- Verwendet die DOM extension
- Support für die meisten EXSLT Erweiterungen (www.exslt.org)
- Ermöglicht die Verwendung von PHP Funktionen innerhalb der XSLT-Templates
- Transformiert DOM in DOM, XML oder URIs (Files)
Ersetzt die XSLT extension von PHP 4.
31: XSLT Stylesheet - Beispiel
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml"
version="1.0"
indent="yes"
encoding="ISO-8859-1"
media-type="text/xml"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
<xsl:template match="/">
<html>
<body bgcolor="#ffffff">
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="book/title">
<h1><xsl:value-of select="."/></h1>
</xsl:template>
<xsl:template match="chapter">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="chapter/title">
<h2><xsl:value-of select="." /></h2>
</xsl:template>
<xsl:template match="para">
<p><xsl:apply-templates/></p>
</xsl:template>
</xsl:stylesheet>
32: XSLT Transformation - Beispiel
<?php
$path = dirname(__FILE__) . '/';
# XSLT Stylesheet als "normales" XML-DOM Dokument laden
$xslDom = new domdocument;
$xslDom->load($path . 'book.xsl');
# XML-Daten laden
$xmlDom = new domdocument;
$xmlDom->load($path . 'book.xml');
$xsl = new XsltProcessor; // XSLT Prozessor Objekt erzeugen
$xsl->importStylesheet($xslDom); // Stylesheet laden
echo $xsl->transformToXML($xmlDom); // Transformation - return XHTML
?>
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body bgcolor="#ffffff">
<h1>This is an Example-Book</h1>
<h2>Title from Chapter 1</h2>
<p>Text in chapter 1</p>
<h2>Title from Chapter 2</h2>
<p>Text in chapter 2</p>
</body>
</html>
33: Praktisches Beispiel: xphp-slides
xphp-slides = XML->PHP5->XSLT->toXHTML();
Anhand des praktischen Beispiels "xphp-slides" soll die Mächtigkeit von PHP5, XML und XSLT gezeigt werden.
Diese Präsentation selber ist auch mit "xphp-slides" erstellt worden.
34: Funktionsweise von xphp-slides
Der Inhalt der Präsentation wird in eine XML-Datei geschrieben aus der mittels PHP5 und eines XSLT-Templates die statischen XHTML-Seiten erzeugt werden.
Die Formatierung erfolgt anhand von CSS.
Die XML-Datei muss der xphp-slides.dtd entsprechen.
Die DTD importiert neben den (wenigen) eigenen Element-Definitionen für die Präsentation die komplette XHTML-DTD, was es ermöglicht, innerhalb der <slide>Tags alle validen XHTML-Tags zu verwenden welche innerhalb einer normalen XHTML-Seite im <body> Tag stehen dürfen.
Mit XML/DTD fähigen Editoren können anhand der DTD beim Schreiben Features wie Syntax-Prüfung, Auto-Vervollständigen, etc. genutzt werden.
Für die Gimmicks der Slides, wie Navigation mit Hot-Keys und inkrementelle Anzeige von Inhalten wird ein wenig JavaScript verwendet.
Die mit xphp-slides erzeugten Präsentationen funktionieren aber auch mit ganz simplen Text-Browsern! Dann eben nur nicht ganz so hübsch ;-)
35: Struktur der XML-Source Datei
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE presentation SYSTEM "xphp-slides.dtd" >
<presentation>
<metainfo>
<title>Beispiel Präsentation</title>
<subtitle>Kleine Beispiel Präsentation für die xphp-slides</subtitle>
<date>2007-03-04</date>
<event>Dummy-Konferrenz</event>
<licence><a href="http://creativecommons.org/licenses/by-nc-nd/2.0/de/deed.de">© Hans Muster</a></licence>
<language>de</language>
<author>
<name>Hans Muster</name>
<email>hans.muster@example.org</email>
<url>http://www.example.org/</url>
<desc>
Angestellter bei <a
href="http://www.example.org/">example.org</a> im Bereich
PHP-Entwicklung.
</desc>
</author>
</metainfo>
<slide><title>Sample-Slide</title>
<p>Beliebiger XHTML-Code innerhalb der <slide>Tags</p>
</slide>
</presentation>
36: Struktur der erstellten XHTML-Seiten
- Die Startseite index.html wird aus den Meta-Informationen der Präsentation erstellt
- Die einzelnen <slide> Tags innerhalb der Präsentation werden jeweils in einzelne XHTML-Seiten exportiert. Seiten-Namen werden durchnummeriert: slide-1.html, slide-2.html, usw.
- Zusätzlich wird ein Inhaltsverzeichnis toc.html erstellt und auf den Einzelseiten verlinkt.
- Jede Einzelseite erhält beim Export die passende [vor] [zurück] Navigation, Links zum Inhaltsverzeichnis usw. Mit ein wenig Javascript kann die Navigation auch mit den üblichen Hot-Keys bedient werden kann.
- Die komplette Präsentation wird zusätzlich zu den Einzelseiten noch in eine All-In-One XHTML-Seite exportiert.
37: Auszeichnungsmöglichkeiten des Inhalts
- Die Start-Seite erhält ein umschliessendes <div id="slide0"> Tag und kann damit über CSS gesondert formatiert werden. (Größere Schriften o.ä.)
- Den <slide> Tags selber kann optional auch eine CSS-Klasse vergeben werden, um diese gruppiert formatieren zu können.
- Innerhalb der <slide>Tags können alle validen XHTML Tags verwendet werden.
- XHTML-Elemente innerhalb des <slide>Tags werden incl. deren Attributen 1:1 durchgereicht.
38: Specials: Ausgabe von PHP-Code
Innerhalb der Slides kann mittels des Elementes <code> und einem CDATA Block beliebiger Programm-Code geschrieben werden.
Wenn das Attribut class="php" vergeben ist, wird der PHP-Code von einer externen PHP-Funktion beim Transformieren mit XSLT mit der externen PHP-Funktion highlight_string() syntax-ge-highlighted dargestellt.
Damit das XSLT-Template aber auch mit nicht-PHP Prozessoren funktioniert, wird im Template eine Variable geprüft.
D.h. zur Aktivierung der PHP-Funktion muss von aussen (im PHP-Script) der Parameter xsltproc=php mit XSLTProcessor::setParameter() gesetzt werden.
<xsl:template match="code[@class='php']">
<div class="phpcode">
<xsl:choose>
<xsl:when test="$xsltproc='php'">
<xsl:value-of select="php:functionString('highlight_string', string(.), 1)"
disable-output-escaping="yes"/>
</xsl:when>
<xsl:otherwise>
<pre>
<xsl:apply-templates/>
</pre>
</xsl:otherwise>
</xsl:choose>
</div>
</xsl:template>
39: Specials: PHP-Code
Beispiel:
<code class="php"><![CDATA[
<?php
phpinfo();
?>
]]></code>
<?php
phpinfo();
?>
40: Specials: Inkrementelle Anzeige
Nunja, gehört wohl dazu: Innerhalb eines Slides sollen z.B. durch drücken der Space-Taste Listen-Punkte nacheinander eingeblendet werden.
Für alle Elemente, die nacheinander eingeblendet werden sollen, muss hier nur die CSS-Klasse class="incremental" vergeben werden. Für Listen (ul,ol,dl) reicht es, wenn der Listen-Tag selber diese Klasse erhält, den Items (li, dd, dt) wird dieses Attribut im XSLT-Template automatisch zugeordnet.
- OL-Item
- OL-Item
- OL-Item mit Sub-Liste:
- Sub Item 1
- Sub Item 2
- dt = definition (list) term
- dd = definition (list) definition = Definition in der Definitionsliste
Ganz einfach oder?
Alle Elemente, des Slides, die nicht als inkrementell getagged sind, werden sofort angezeigt, auch die, die hinter/unter den inkrementellen stehen.
41: Technik: PHP Teil beim Erstellen der Slides
Ein kleines PHP-CLI Script xphp-slides.php nimmt die Parameter für die Quelldatei und das Ausgabeverzeichnis entgegen, erstellt die notwendigen Objekte und wirft den XSLT Prozessor an, welcher die Ausgabeseiten erstellt.
--------------------------------------------------
Usage:
./xphp-slides.php -i SOURCE.xml -o OUTPUT_DIR [-h]
Options:
-i source XML file
-o output dir for the presentation
-h show this help
--------------------------------------------------
42: Technik: PHP Teil beim Erstellen der Slides
Da die komplette Ausgabe-Logik zum Erstellen der Ausgabeseiten im XSLT-Template hinterlegt bzw. vom XSLT-Prozessor übernommen wird, braucht es sehr wenig PHP um die Seiten zu rendern.
Der eigentliche Programmcode, beschränkt sich im Wesentlichen auf diese paar Zeilen:
<?php
// laden des XSLT Stylesheet als regulaere XML Datei via DOM
$xslDom = new domdocument;
$xslDom->load($xsl_file);
// laden der XML-Daten Datei via DOM
$xmlDom = new domdocument;
// $xmlDom->resolveExternals = true;
$xmlDom->load($xml_src);
// initialisieren des XSLT Processors
$xslt = new XsltProcessor;
// Optional: registrieren von PHP-Funktions im XSL
$xslt->registerPhpFunctions();
// Ausgabeverzeichnis als Parameter fuer das XSL setzen
$xslt->setParameter('', 'outdir', $outdir);
// PHP XSLT Processors als Parameter fuer das XSL setzen um darin die
// optionalen Funktionen zu nutzen.
// PHP braucht das nicht, aber wenn das XSL-Template auch mit anderen
// XSLT-Prozessoren genutzt werden soll, muss vor der Verwendung eine
// Abfrage rein, denn nur PHP kennt die PHP-Funktionen.
$xslt->setParameter('', 'xsltproc', 'php');
// XSL-Stylesheet importieren
$xslt->importStylesheet($xslDom);
// Transformation ausfuehren -> return XML/HTML
$xslt->transformToXML($xmlDom);
?>
43: Technik: das XSLT-Template
Da bei der Ausgabe reines XHTML erstellt wird und damit die Formatierung komplett über CSS zu machen ist, ist es in der Regel nicht notwendig am XSLT-Template Änderungen vorzunehmen.
Verbessern kann man natürlich alles ;-)
Neben den üblichen Elementen für die Ausgabe-Logik, wie Loops, ifs, etc. ist der eigentliche Trick des xphp-slides Templates die Verwendung der erweiterten Funktionen, die EXSLT bietet und welche der PHP-XSLT-Prozessor dankenswerterweise unterstützt.
Normalerweise kann ein XSLT-Template nur eine Ausgabe erzeugen:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml"
encoding="ISO-8859-1"
omit-xml-declaration="yes"
/>
<!-- [..] -->
</xsl:stylesheet>
44: Technik: das XSLT-Template und EXSLT
Durch das Einbinden der EXSLT common Erweiterung ist es mit dem <exsl:document> Element aber möglich mehrere Ausgabe-Dokumente zu erzeugen.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet SYSTEM "xslt10.dtd" >
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:php="http://php.net/xsl"
extension-element-prefixes="exsl php"
exclude-result-prefixes="exsl php"
>
<!-- [..] -->
<!-- Pro slide Tag Einzel-Seite der Praesentation erzeugen -->
<xsl:template match="slide" name="slide">
<exsl:document
href="{$outdir}/slide-{$slidenr}.html"
method="xml"
version="1.0"
indent="yes"
encoding="ISO-8859-1"
omit-xml-declaration="no"
standalone = "yes"
media-type="text/xml"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<!-- [..] -->
45: xphp-slides - DEMO
So, genug der Theorie, jetzt noch eine kleine DEMO mit xphp-slides.
46: Links
PHP Extensions:- XML (SAX) Docs : http://www.php.net/xml
- SimpleXML Docs : http://www.php.net/simplexml
- DOM Docs : http://www.php.net/dom
- XSL Docs : http://www.php.net/xsl
- SOAP Docs : http://www.php.net/soap
- XML-RPC Docs: http://www.php.net/xml-rpc
- XML-Writer Docs: http://www.php.net/xmlwriter
- XML-Reader Docs: http://www.php.net/xmlreader
- W3C XML: http://www.w3.org/XML/
- W3C XML in deutsch: http://edition-w3c.de/TR/2000/REC-xml-20001006/
- W3C XPath: http://www.w3.org/TR/xpath
- W3C XPath in deutsch: http://www.edition-w3c.de/TR/xpath
- W3C XSL: http://www.w3.org/TR/xsl/
- W3C XSLT: http://www.w3.org/TR/xslt
- W3C XSLT in deutsch: http://www.edition-w3c.de/TR/xslt
- W3C DOM: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html