XML mit PHP und Expat parsen XML ist das Datenformat der Zukunft. Mit der PHP Erweiterung Expat kann man XML durch PHP parsen. Dadurch eröffnen sich viele neue Möglichkeiten.

XML ist als reine Datensprache viel mächtiger als einfache SQL basierende Datenbanken, die sich auf dem zweidimensionalen Rahmen beschränken. Mit XML sind vielfach ineinander verschachtelte Datensysteme möglich.

Die Erkennung der einzelnen Daten aus XML Dateien, und deren dynamische Veränderung ist ungemein wichtig, da man ohne diese Funktionalität nicht effektiv auf XML Datenbanken zurückgreifen kann.
Speziell für Webanwendungen ist es in dieser Hinsicht schwierig mit XML umzugehen.
Eine einfache Möglichkeit mit XML Daten umzugehen bietet Expat. Expat ist in die PHP 4 Version integriert, und kann bei der Installation durch die Option "-with-xml" installiert werden.
Expat ist ereignisorientiert. Das bedeutet, das zunächst einzelne Funktionen für die verschiedene Ereignisse definiert werden.
Ein Ereignis kann z.B. ein öffnendes Element, ein schließendes Element oder der Inhalt, der von einem öffnenden, und einem schließendem Element eingeklammert ist, sein.

Für folgende Elemente können Funktionen definiert werden.

  • Startendes Element, mit Attributen (<inhalt nr="10">)
  • Normaler Text "Character Data", zwischen den öffnendem und schließendem Element
  • Abschließendes Element (</inhalt>)
  • Kommentare
  • DTD Anweisungen
  • Procession Instructions - eingebettete PHP Anweisungen

Wichtig ist, das man die Arbeitsweise von Expat versteht. Expat untersucht ein XML Dokument zeilenweise. Aufgrund dessen muss das Dokument Zeile für Zeile, also über eine Schleife von Expat geparset werden.
Expat erkennt das öffnende Element, z.B. <inhalt>, und übergibt es an die definierte Funktion für öffnende Elemente. Darauf entdeckt er den Inhalt dazwischen. Ist dies einfacher Text, dann wird dieser an die entsprechende Funktion überreicht, die die Inhalte behandelt. Diese Inhalte, die nicht weiter in andere Tags verschachtelt sind, nennt man CDATA, Character Data. Zum Schluss wird das schließende Element gefunden, und entsprechend über die definierte Funktion behandelt.

Einen XML Parser erzeugen

Ein XML Parser wird immer für das XML Dokument individuell erzeugt.

$parser = xml_parser_create();
Der Parser wird erzeugt. Die Variable $parser verweist auf den erzeugten Parser, sodass dieser einmalig gekennzeichnet ist.

xml_set_element_handler($parser,"startElement","endElement");
Hiermit werden die Funktionen für das öffnende, und das schließende Element angegeben. "startElement" verweist auf die entsprechende Funktion startElement(), und endElement verweist auf die entsprechende Funktion "endElement".

xml_set_character_data_handler($parser, "characterdata");
Hiermit wird auf die Funktion für CDATA (normaler Text) verwiesen.

xml_set_processing_instruction_handler($parser, "pi");

Hier wird auf die Funktion verwiesen, die Processing Instructions behandelt (mehr dazu im zweiten Teil).

xml_set_default_handler($parser, "default");

Diese Funktion wird aufgerufen, wenn für das Ereignis keine andere Funktion definiert ist. Man kann sagen, das die default-Funktion aufgerufen wird, wenn ein Fehler aufgetreten ist, z.B. wenn man sich verschrieben hat usw.

Der erste eigene Parser

Die Arbeitsweise von Expat sollte nun im kleinen zumindest klar sein. Hier nun unser erster kleiner Parser, der auf das folgende XML Dokument zugeschnitten ist.

inhalt.xml

<?xml version="1.0"?>
<inhalt>
Irgend ein Text, der nur dasteht, um
Platz zu verschwenden.
</inhalt>


Diese XML Datei wird von dem folgendem Parser geparsed.

inhalt.php


<?php

function startElement($parser, $element_name, $element_attribute) {
global $ausgabe;
//Umwandeln in Kleinbuchstaben
$element_name = strtolower($element_name);
//Überprüfung des Elementnames
if ($element_name=="inhalt") {
$ausgabe .= "<h3>Inhalt</h3><p>";
}
}
function endElement($parser, $element_name) {
global $ausgabe;
// in Kleinbuchstaben umwandeln
$element_name = strtolower($element_name);
// Überprüfung des Names eines Elementes
if ($element_name=="inhalt") {
$ausgabe .= "</p>";
}
}
function cdata($parser, $element_inhalt) {
global $ausgabe;
// Der normale Text wird an $ausgabe angehängt
$ausgabe .= $element_inhalt;
}
$xmlFile = file("inhalt.xml");
$parser = xml_parser_create();
xml_set_element_handler($parser, "startElement", "endElement");
xml_set_character_data_handler($parser, "cdata");

foreach($xmlFile as $elem)
{
xml_parse($parser, $elem);
}
xml_parser_free($parser);

echo $ausgabe;
?>

Die Ausgabe nach dem Aufruf des Skriptes sieht wie folgt aus:

Ihr erstes von PHP geparstes XML Dokument
Ihr erstes von PHP geparstes XML Dokument


Um die Arbeitsweise des Skriptes zu verstehen, sollte jede der definierten Funktionen einzelne bearbeitet werden.

Zunächst behandeln wir die Funktion, die aufgerufen wird, wenn Expat ein öffnendes Element findet. In unserem Beispiel ist das <inhalt>.
An die Funktion wird die Variable $parser übergeben. In ihr wird auf den erzeugten XML Parser verwiesen. Über die Variable $element_name wird der Names des Elementes übergeben. In unserem Beispiel ist der Name des Elementes "inhalt". Zudem kann an die Funktion die Attribute, und deren Werte übergeben werden. Wie Sie diese mit XML Parsen erfahren Sie im zweiten Teil des Workshops.
In der ersten Zeile der Funktion selbst wird auf die Variable $ausgabe verwiesen, und ihr Globale Eigenschaften gegeben. D.h. die Variable ist nicht nur in der Funktion vorhanden, sondern auf außerhalb. So kann man direkt auf den Wert der Variablen zugreifen, ohne diesen an die Funktion zu übergeben. Zudem kann der Wert auf direkt aus der Funktion heraus verändert werden.

function startElement($parser, $element_name, $element_attribute) {
global $ausgabe;
//Umwandeln in Kleinbuchstaben
$element_name = strtolower($element_name);
//Überprüfung des Elementnames
if ($element_name=="inhalt") {
$ausgabe .= "<h3>Inhalt</h3><p>";
}
}

Die nächste Anweisung wandelt den Namen des Elementes in Kleinbuchstaben um, da Expat die Namen eines Elementes immer in Großbuchstaben übergibt. Dies muss nicht gemacht werden, dient aber zu einem einfacheren Verständnis des Codes.
Im nächsten Teil wird überprüft, ob der Name des Elementes "inhalt" ist. Ist dies der Fall, dann wird an die Globale Variable $ausgabe der Inhalt "<h3>Inhalt</h3><p>" über den Stringoperator "." angehängt.

Eigentlich ist eine Überprüfung auf den Namen des Elementes nicht notwendig, da in der XML Datei sowieso nur ein Element vorkommt. Da wir jedoch in den nächsten Teil des Workshops mit etwas komplexeren Beispielen in die Materie einsteigen, sollte auf diese zwei Zeilen Code nicht verzichtet werden.

Nun, wollen wir uns mit der Funktion für den normalen Fließtext, CDATA kümmern. Diese hat nur eine Aufgabe. Sie muss den Inhalt des Elemenets an die Globale Variable $ausgabe anhängen.

function cdata($parser, $element_inhalt) {
global $ausgabe;
// Der normale Text wird an $ausgabe angehängt
$ausgabe .= $element_inhalt;
}


Der Inhalt des aktuell geparten Element wird über die Variable $element_inhalt übergeben. Dieser wird an die Variable $ausgabe angehängt.

Die letzte Funktion ist für die schließenden Elemente zuständig. Diese Funktion arbeitet auf der gleichen Weise, wie die Funktion für das öffnende Element.

function endElement($parser, $element_name) {
global $ausgabe;
// in Kleinbuchstaben umwandeln
$element_name = strtolower($element_name);
// Überprüfung des Names eines Elementes
if ($element_name=="inhalt") {
$ausgabe .= "</p>";
}
}


Das sind die Funktionen, die in diesem Beispiel benötigt werden. Nun muss die XML Datei eingelesen werden, und daraufhin der Parser definiert bzw. erzeugt werden.

$xmlFile = file("inhalt.xml");
$parser = xml_parser_create();
xml_set_element_handler($parser, "startElement", "endElement");
xml_set_character_data_handler($parser, "cdata");

foreach($xmlFile as $elem)
{
xml_parse($parser, $elem);
}
xml_parser_free($parser);

echo $ausgabe;


In der ersten Zeile wird die Datei über die file() Funktion in ein Array gelesen. In der zweiten Zeile wird der Parser erzeugt. Darauf werden die einzelnen Handler festgelegt.
Der letzte und wichtigste Teil des Skriptes ist, das der Inhalt des Arrays über eine foreach-Schleife einzeln über die Funktion xml_parse() geparsed wird.
In der vorletzten Zeile wird der Parser wieder "zerstört", d.h. alle belegten Resourcen werden wieder frei gegeben. In der letzten Zeile wird nun der Inhalt der Variablen $ausgabe ausgegeben. In ihr befindet sich der Inhalt, der über die einzelnen Funktionen "dynamisch" aus der XML Datei extrahiert wurde.
(tf)

Bookmark setzen... These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Bloglines
  • MisterWong
  • MySpace
  • Reddit
  • SEOigg
  • Technorati
  • TwitThis
  • Y!GG
  • Google Bookmarks

Keine weiterführenden Beiträge.