Mit dem Document Object Model (DOM) bietet das World Wide Web Consortium (W3C) einen mächtigen Standard an, der eine plattform- und sprachunabhängige neutrale Programmierschnittstelle für den lesenden und schreibenden Zugriff auf gültige HTML und wohlgeformte XML-Dokumente definiert.
PHP 5 bietet mit seiner DOM-Erweiterung, die nicht abwärtskompatibel zur DOM-XML-Erweiterung von PHP 4 ist, eine vollständige Implementierung der "Level 2 Core"-Version des DOM-Standards. Teilweise werden auch Bestandteile ("Load and Save") der neueren Version "Level 3" umgesetzt.
Das Document Object Model fasst jeden Bestandteil eines XML-Dokumentes
als einen Knoten auf. Das Dokument selbst (DOMDocument),
seine Elemente (DOMElement) sowie deren Attribute
(DOMAttr) und textuelle Inhalte (DOMText)
werden durch Objekte entsprechender Knotenklassen repräsentiert, die
untereinander mit Referenzen verknüpft sind.
Abbildung 8.3
zeigt den DOM-Objektbaum für das XML-Dokument aus
Beispiel 8.1.
Die DOM-Implementierung von PHP 5 umfasst 29 Klassen mit insgesamt 360 Methoden. Wir konzentrieren uns an dieser Stelle auf die wichtigsten (Tabelle 8.1).
Tabelle 8.1. Die wichtigsten Klassen des Document Object Model
| Klasse | Elternklasse oder Schnittstelle | Aufgabe |
|---|---|---|
DOMNode | Basisklasse der verschiedenen Knotenklassen eines DOM-Baumes. | |
DOMDocument | DOMNode | Bildet den Einstiegspunkt des DOM-Baumes. |
DOMElement | DOMNode | Repräsentiert ein XML-Element und bietet Methoden für den Zugriff auf XML-Elemente. |
DOMAttr | DOMNode | Repräsentiert ein Attribut eines XML-Elementes. |
DOMCharacterData | DOMNode | Repräsentiert den Character-Data-Teil eines XML-Elementes. |
DOMText | DOMCharacterData | Repräsentiert textuelle Inhalte eines XML-Dokuments. |
DOMNodeList | Traversable | Repräsentiert eine Menge von Knoten. |
DOMXPath | Ermöglicht das Formulieren von XPath-Anfragen. | |
DOMException | Exception | Ausnahmeklasse. |
Die Methode DOMDocument::load($filename), die sowohl auf
einem Objekt als auch statisch aufgerufen werden kann, lädt ein
XML-Dokument aus einer Datei. Wird die Methode statisch aufgerufen,
so liefert sie ein Objekt der Klasse DOMDocument als
Ergebnis (siehe beispielsweise
Beispiel 8.12).
DOMDocument::loadXML($xml) lädt ein XML-Dokument aus einem
String, die Funktion dom_import_simplexml($sxe) erzeugt
ein Objekt der Klasse DOMDocument aus einem Objekt der
Klasse SimpleXMLElement.
Analog laden die Methoden DOMDocument::loadHTMLFile($filename)
und DOMDocument::loadHTML($html) ein HTML-Dokument aus
einer Datei oder aus einem String.
Die Methoden DOMDocument::save($filename) und
DOMDocument::saveXML() speichern ein
DOMDocument-Objekt als XML-Daten in eine Datei oder
einen String. Für HTML-Dokumente gibt es entsprechend die Methoden
DOMDocument::saveHTMLFile($filename) und
DOMDocument::saveHTML().
Die genannten Methoden nutzen das Streams-System von PHP 5 und können
daher, je nachdem welche Stream-Unterstützungen in PHP einkompiliert
wurden, beispielsweise eine XML-Datei von einem entfernten HTTP-Server
öffnen oder auf einem FTP-Server speichern. An Stelle eines
Dateinamens ist hierbei die entsprechende URL als $filename
anzugeben.
In Beispiel 8.9
erzeugen wir zunächst ein Objekt der Klasse DOMDocument. Dem
Konstruktor übergeben wir die gewünschte Version des XML-Standards
('1.0') und die zu verwendende Zeichenkodierung
('iso-8859-1').
Die Methode DOMDocument::createElement() erzeugt ein
neues Objekt der Klasse DOMElement. Über die Methode
DOMNode::appendChild() wird dieses dann an der
gewünschten Stelle in den DOM-Baum "eingehängt".
Beispiel 8.9: Erzeugen eines neuen XML-Dokumentes
<?php
$document = new DOMDocument('1.0', 'iso-8859-1');
$document->formatOutput = TRUE;
$books = $document->appendChild(
$document->createElement('books')
);
$psmp5 = $books->appendChild(
$document->createElement('book')
);
$psmp5->setAttribute('lang', 'de');
$psmp5->appendChild(
$document->createElement(
'author',
'Sebastian Bergmann'
)
);
$psmp5->appendChild(
$document->createElement(
'title',
'Professionelle Softwareentwicklung mit PHP 5'
)
);
$psmp5->appendChild(
$document->createElement(
'isbn',
'3-89864-229-1'
)
);
print $document->saveXML();
?><?xml version="1.0" encoding="iso-8859-1"?>
<books>
<book lang="de">
<author>Sebastian Bergmann</author>
<title>Professionelle Softwareentwicklung mit PHP 5</title>
<isbn>3-89864-229-1</isbn>
</book>
</books>Erzeugen eines neuen XML-Dokumentes durch direkte Verwendung der DOM-Klassen, wie es in Beispiel 8.9 gezeigt ist, kann recht aufwändig werden. In solchen Fällen bietet es sich an, die DOM-Klassen durch Vererbung zu erweitern und für den konkreten Verwendungszweck anzupassen.
Die Klasse Book (Beispiel 8.10)
erweitert die Klasse DOMElement um die für das
<book>-Element spezifischen Methoden
setAuthor($author), setISBN($isbn),
setLanguage($language) und setTitle($title).
So wird dem Verwender der Klasse das Aufrufen von
DOMDocument::createElement() und
DOMNode::appendChild() abgenommen.
Beispiel 8.10: Die Klasse Book
<?php
class Book extends DOMElement {
private $document;
public function __construct(DOMDocument $document) {
parent::__construct('book');
$this->document = $document;
}
public function setAuthor($author) {
$this->appendChild(
$this->document->createElement(
'author',
$author
)
);
}
public function setISBN($isbn) {
$this->appendChild(
$this->document->createElement(
'isbn',
$isbn
)
);
}
public function setLanguage($language) {
$this->setAttribute('lang', $language);
}
public function setTitle($title) {
$this->appendChild(
$this->document->createElement(
'title',
$title
)
);
}
}
?>
Die Klasse Books (Beispiel 8.11)
erweitert die Klasse DOMDocument und bietet mit ihrer
Methode createBook() eine einfache Möglichkeit, ein
neues <book>-Element zu erzeugen.
Beispiel 8.11: Die Klasse Books
<?php
require_once 'Book.php';
class Books extends DOMDocument {
private $books;
public function __construct() {
parent::__construct('1.0', 'iso-8859-1');
$this->books = $this->appendChild(
$this->createElement('books')
);
$this->formatOutput = TRUE;
}
public function createBook() {
$book = new Book($this);
$this->books->appendChild($book);
return $book;
}
}
$books = new Books;
$book = $books->createBook();
$book->setAuthor('Sebastian Bergmann');
$book->setISBN('3-89864-229-1');
$book->setTitle(
'Professionelle Softwareentwicklung mit PHP 5'
);
$book->setLanguage('de');
print $books->saveXML();
?>Beispiel 8.11 erzeugt dieselbe Ausgabe wie Beispiel 8.9.
Die Klasse DOMNodeList repräsentiert eine Menge von
Knoten, also Objekten der Klasse DOMNode. Es wird
keine spezielle Ordnung für die Knoten vorgegeben.
DOMNodeList implementiert die Schnittstelle
Traversable (siehe Kapitel 3),
entsprechende Objekte können daher mit dem foreach-Operator
iteriert werden.
Beispiel 8.12
benutzt die Methode DOMDocument::getElementsByTagName(), um
alle <author>-Elemente zu erhalten. Als Ergebnis
liefert die Methode ein Objekt der Klasse DOMNodeList, das
die entsprechenden DOMElement-Objekte enthält.
$author->nodeValue greift auf den Wert des
DOMText-Knotens zu, der an dem von $author
referenzierten DOMElement-Objekt hängt.
Beispiel 8.12: Verwenden der DOMNodeList-Klasse
<?php
$document = DOMDocument::load('books.xml');
$authors = $document->getElementsByTagName('author');
foreach ($authors as $author) {
print $author->nodeValue . "\n";
}
?>Sebastian Bergmann Hakan Kücükyilmaz Thomas M. Haas Alexander Merz
Über die Klasse DOMXPath können XPath-Anfragen an einen
DOM-Baum gestellt werden. Das Ergebnis ist wieder ein Objekt der
Klasse DOMNodeList.
Beispiel 8.13: Formulieren von XPath-Anfragen
<?php
$document = DOMDocument::load('books.xml');
$xpath = new DOMXPath($document);
foreach ($xpath->query('book/title') as $title) {
print $title->nodeValue . "\n";
}
?>Professionelle Softwareentwicklung mit PHP 5 PHP 5
Neben der Verarbeitung von XML-Dokumenten ermöglicht die PHP-DOM-Erweiterung auch die Validierung von XML-Dokumenten gegen Spezifikationen in den Formaten Document Type Definition (DTD), XML Schema (XSD) und RelaxNG (RNG).
XML Schema ist die offizielle Nachfolgetechnologie des W3C für die Document Type Definition. Ein Schemas wird benutzt, um eine Klasse von XML-Dokumenten zu definieren. Anhand eines Schemas kann für ein konkretes XML-Dokument überprüft werden, ob es die Schema-Definition erfüllt. Man sagt, ein XML-Dokument validiert gegen ein XML Schema.
Beispiel 8.14
zeigt die Verwendung der von PHP 5 zur Verfügung gestellten Methode
DOMDocument::schemaValidate().
Beispiel 8.14: XML-Schema-Validierung
<?php
$document = DOMDocument::load('books.xml');
if ($document->schemaValidate('books.xsd')) {
print 'books.xml entspricht der XML-Schema-Deklaration '.
'in books.xsd.';
}
?>books.xml entspricht der XML-Schema-Deklaration in books.xsd.
Beispiel 8.15: XML-Schema-Deklaration für den Buchkatalog
<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="books">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" ref="book"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="book">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="author" minOccurs="1" maxOccurs="unbounded"/>
<xsd:element ref="title" minOccurs="1"/>
<xsd:element ref="isbn" minOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="lang" use="required" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
<xsd:element name="author" type="xsd:string"/>
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="isbn" type="xsd:string"/>
</xsd:schema>
RelaxNG ist eine parallel zu XML Schema entstandene Schema-Sprache für die Definition von XML-Dokumenten, die derzeit ISO-standardisiert wird. Sie wird nicht vom W3C unterstützt, nutzt aber die von XML Schema definierten Datentypen. RelaxNG tritt an, eine leichter erlernbarere Alternative zu XML Schema zu sein.
Beispiel 8.14
zeigt die Verwendung der Methode DOMDocument::relaxngValidate().
Beispiel 8.16: RelaxNG-Validierung
<?php
$document = DOMDocument::load('books.xml');
if ($document->relaxngValidate('books.rng')) {
print 'books.xml entspricht der RelaxNG-Deklaration '.
'in books.rng.';
}
?>books.xml entspricht der RelaxNG-Deklaration in books.rng.
Beispiel 8.17: RelaxNG-Deklaration für den Buchkatalog
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<start>
<element name="books">
<oneOrMore>
<element name="book">
<attribute name="lang">
<data type="NMTOKEN"/>
</attribute>
<oneOrMore>
<element name="author">
<text/>
</element>
</oneOrMore>
<element name="title">
<text/>
</element>
<element name="isbn">
<text/>
</element>
</element>
</oneOrMore>
</element>
</start>
</grammar>