Für die einfache Verarbeitung von XML-Dokumenten bietet PHP die
SimpleXML-Programmierschnittstelle an. Diese baut auf der Idee des
Perl-Paketes XML::Simple auf und bietet einen intuitiven
Zugriff auf XML-Daten.
Die Funktionen simplexml_load_file() und
simplexml_load_string() erzeugen ein Objekt
der Klasse SimpleXMLElement für die
Verarbeitung von XML-Daten, die aus einer Datei beziehungsweise
aus einem String gelesen werden.
Die Methode asXML($filename) liefert die XML-Daten
eines SimpleXMLElement-Objektes als XML-Daten und
schreibt diese optional in eine Datei.
Ein Objekt der Klasse SimpleXMLElement enthält für jedes
XML-Kindelement eine Instanzvariable, die den entsprechenden Namen trägt
(siehe Abbildung 8.2).
Kommt dieses nur einmal vor, so ist der Wert der Instanzvariablen der
Wert des Kindelementes. Kommt das Kindelement
(wie <book> in Beispiel 8.1)
mehrfach vor, so enthält die Instanzvariable ein Array
[9]
von SimpleXMLElement-Objekten für die Kindelemente.
Beispiel 8.1: Ein Buchkatalog im XML-Format
<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE books PUBLIC "books" "books.dtd">
<books>
<book lang="de">
<author>Sebastian Bergmann</author>
<title>Professionelle Softwareentwicklung mit PHP 5</title>
<isbn>3-89864-229-1</isbn>
</book>
<book lang="de">
<author>Hakan Kücükyilmaz</author>
<author>Thomas M. Haas</author>
<author>Alexander Merz</author>
<title>PHP 5</title>
<isbn>3-89864-236-4</isbn>
</book>
</books>
Abbildung 8.2. Repräsentation der XML-Daten in einem SimpleXMLElement-Objekt
SimpleXMLElement Object
(
[book] => Array
(
[0] => SimpleXMLElement Object
(
[author] => Sebastian Bergmann
[title] => Professionelle Softwareentwicklung mit PHP 5
[isbn] => 3-89864-229-1
)
[1] => SimpleXMLElement Object
(
[author] => Array
(
[0] => Hakan Kücükyilmaz
[1] => Thomas M. Haas
[2] => Alexander Merz
)
[title] => PHP 5
[isbn] => 3-89864-236-4
)
)
)
Da ein SimpleXMLElement-Objekt über eine Implementierung
des __toString()-Interzeptors (siehe „__toString“)
verfügt, kann auf den Inhalt (CDATA) eines XML-Elementes wie auf einen
String zugegriffen werden, beispielsweise über print.
Beispiel 8.2
zeigt den Zugriff auf den Inhalt des title-Elementes
des ersten book-Elementes.
Beispiel 8.2: Zugriff auf ein XML-Element mit SimpleXML
<?php
$books = simplexml_load_file('books.xml');
print $books->book[0]->title;
?>Professionelle Softwareentwicklung mit PHP 5
Die Methode attributes() eines SimpleXMLElement-Objektes
liefert ein assoziatives Array mit den Attributen eines XML-Elementes.
Beispiel 8.3: Zugriff auf ein XML-Attribut mit SimpleXML
<?php
$books = simplexml_load_file('books.xml');
foreach ($books->book[0]->attributes() as $name=>$value) {
print "$name: $value\n";
}
?>lang: de
Die Klasse SimpleXMLElement implementiert die
Iterator-Schnittstelle Traversable (siehe Kapitel 3).
Ein SimpleXMLElement-Objekt kann daher mit dem
foreach-Operator iteriert (und damit die darin
gekapselten XML-Daten verarbeitet) werden, wie
Beispiel 8.4
zeigt.
Beispiel 8.4: Zugriff auf den Buchkatalog mit SimpleXML und foreach()
<?php
$books = simplexml_load_file('books.xml');
foreach ($books->book as $book) {
$authors = '';
foreach ($book->author as $author) {
$authors .= empty($authors) ? $author : ', ' . $author;
}
printf(
"%s: \"%s\"\nISBN: %s\n\n",
$authors,
$book->title,
$book->isbn
);
}
?>Sebastian Bergmann: "Professionelle Softwareentwicklung mit PHP 5" ISBN: 3-89864-229-1 Hakan Kücükyilmaz, Thomas M. Haas, Alexander Merz: "PHP 5" ISBN: 3-89864-236-4
Der Inhalt von SimpleXMLElement-Objekten kann durch
Zugriff auf die entsprechenden Instanzvariablen geändert
werden, wie
Beispiel 8.5
zeigt.
Beispiel 8.5: Ein SimpleXMLElement-Objekt ändern und als XML ausgeben
<?php
$books = simplexml_load_file('books.xml');
$books->book[0]->author = 'Johannes Sebastian Bergmann';
print $books->book[0]->asXML();
?><book lang="de"> <author>Johannes Sebastian Bergmann</author> <title>Professionelle Softwareentwicklung mit PHP 5</title> <isbn>3-89864-229-1</isbn> </book>
Über die Methode xpath() eines
SimpleXMLElement-Objektes können Anfragen in der
XML Path Language (XPath) gestellt werden.
Beispiel 8.6
zeigt eine Anfrage, die die Titel der im Katalog enthaltenen Bücher
liefert. Das Ergebnis einer solchen Anfrage ist ein Array von
SimpleXMLElement-Objekten.
Beispiel 8.6: Verwenden von XPath mit SimpleXML
<?php
$books = simplexml_load_file('books.xml');
foreach ($books->xpath('book/title') as $title) {
print "$title\n";
}
?>Professionelle Softwareentwicklung mit PHP 5 PHP 5
Mit der Klasse SimpleXMLIterator bietet die Standard PHP
Library (siehe Kapitel 3) eine Alternative
zu SimpleXMLElement an, um die Elemente eines
XML-Dokumentes für die Verarbeitung mit SimpleXML zu kapseln.
SimpleXMLIterator bietet die Schnittstelle
RecursiveIterator an, und kann daher mit einem
RecursiveIteratorIterator rekursiv alle Elemente
eines XML-Dokumentes aufzählen.
In Beispiel 8.7
rufen wir die Funktion simplexml_load_file() mit ihrem
optionalen zweiten Parameter auf, um einen SimpleXMLIterator
anstelle eines SimpleXMLElement-Objektes zu erhalten. Im
Anschluss erzeugen wir einen RecursiveIteratorIterator für
den SimpleXMLIterator. Dieser zählt alle XML-Elemente
einschließlich der Wurzel (RIT_SELF_FIRST) auf.
Beispiel 8.7: Rekursives Aufzählen der Elemente eines XML-Dokumentes
<?php
$document = simplexml_load_file(
'books.xml',
'SimpleXMLIterator'
);
$iterator = new RecursiveIteratorIterator(
$document,
RIT_SELF_FIRST
);
foreach($iterator as $name => $element) {
print $name . "\n";
}
?>book author title isbn book author author author title isbn
Innerhalb der foreach-Schleife aus
Beispiel 8.7
enthält die Variable $name den Namen des aktuellen
XML-Elementes und $element das entsprechende Objekt.
+ Einfacher Zugriff auf XML-Element.
+ Geringer Speicherverbrauch, da PHP-Objekte nur bei Bedarf erzeugt werden und das Dokument zu Beginn nur einmal (im Speicher der libxml2-Bibliothek) vorliegt.
+ Schnell.
- Zugriff auf Attribute eines XML-Elementes umständlich.
- Kein Standard.
[9]
Die PHP-Array-Funktionen können auf ein solches Array nicht
angewendet werden. is_array($books->book[1]->author)
liefert in unserem Beispiel FALSE als Ergebnis.
Die PHP-Debug-Funktionen print_r() und
var_dump() zeigen allerdings $books->book[1]->author
als Array.