SimpleXML

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.

Laden und Speichern von XML-Dokumenten

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.

Die Klasse SimpleXMLElement

Abbildung 8.1. Die Klasse SimpleXMLElement

Die Klasse SimpleXMLElement


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


Die Klasse SimpleXMLIterator

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.

Vor- und Nachteile

  • + 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.