Bei der Verarbeitung von XML-Daten mit der Simple API for XML (SAX) ruft der XML-Parser für bestimmte Ereignisse (öffnendes Element-Tag, ...) vom Programmierer zuvor bestimmte Funktionen oder Methoden auf. Die XML-Daten werden so ereignisorientiert verarbeitet.
Wir betrachten zunächst die drei Ereignisse, die bei der Verarbeitung von XML-Daten am wichtigsten sind: "Start Element", "End Element" und "Character Data".
xml_set_element_handler($parser, <start_element_handler>, <end_element_handler>)
registriert die Callbacks für die Ereignisse "Start Element" und
"End Element".
Die Funktion oder Methode, die für das Ereignis "Start Element"
aufgerufen werden soll, muss drei Parameter $parser,
$name und $attributes akzeptieren. Letzterer
enthält ein assoziatives Array der Attribute des XML-Elementes.
Die Funktion oder Methode, die für das Ereignis "End Element"
aufgerufen werden soll, muss zwei Parameter $parser und
$name akzeptieren.
xml_set_character_data_handler($parser, <handler>)
registriert den Callback für das Ereignis "Character Data".
Die Funktion oder Methode, die für das Ereignis "Character Data"
aufgerufen werden soll, muss zwei Parameter $parser und
$cdata akzeptieren.
Bei der Registrierung eines Callbacks kann als <handler>
der Name einer Funktion oder ein Array, das eine Referenz auf ein
Objekt sowie den Namen der für das Ereignis aufzurufenden Methode des
Objektes enthält, angegeben werden.
Beispiel 8.8 zeigt die Verarbeitung des Buchkatalogs (Beispiel 8.1).
Beispiel 8.8: Zugriff auf den Buchkatalog mit SAX
<?php
class Books {
protected $parser;
protected $elementStack = array();
protected $authors = array();
public function __construct() {
$this->parser = xml_parser_create();
xml_set_object($this->parser, $this);
xml_set_element_handler(
$this->parser,
'startElement',
'endElement'
);
xml_set_character_data_handler(
$this->parser,
'characterData'
);
xml_set_default_handler(
$this->parser,
'characterData'
);
}
public function __destruct() {
xml_parser_free($this->parser);
}
public function readCatalog($catalog) {
xml_parse(
$this->parser,
file_get_contents($catalog),
TRUE
);
}
protected function
startElement($parser, $element, $attributes) {
array_push($this->elementStack, $element);
if ($element == 'BOOK') {
$this->authors = array();
}
}
protected function endElement($parser, $element) {
array_pop($this->elementStack);
}
protected function characterData($parser, $cdata) {
$level = sizeof($this->elementStack) - 1;
$element = $this->elementStack[$level];
switch($element) {
case 'AUTHOR': {
$this->authors[] = $cdata;
}
break;
case 'TITLE': {
print implode(', ', $this->authors) . "\n";
print $cdata . "\n";
}
break;
case 'ISBN': {
print 'ISBN: ' . $cdata . "\n\n";
}
break;
}
}
}
$books = new Books;
$books->readCatalog('books.xml');
?>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
Da der SAX-Parser die XML-Daten linear verarbeitet und stets nur die Daten im Speicher hält, die zu dem aktuellen Ereignis gehören, muss der Programmierer Buch über Daten wie das aktuelle Element führen. In unserem Beispiel legen wir hierzu den Namen des Elementes bei einem öffnenden XML-Tag auf einen Stapel. Im Callback für Character Data können wir so nachvollziehen, zu welchem Element die aktuellen Daten gehören. Erreicht der Parser das schließende XML-Tag, so entfernen wir den Namen des Elements wieder von dem Stapel.
Die Simple API for XML bietet über die Behandlung der Ereignisse "Start Element", "End Element" und "Character Data" hinaus die folgenden Callbacks an:
xml_set_processing_instruction_handler($parser, <handler>)
registriert den Callback für das Ereignis "Processing Instruction".
xml_set_external_entity_ref_handler($parser, <handler>)
registriert den Callback für das Ereignis "External Entity Reference".
xml_set_notation_decl_handler($parser, <handler>)
registriert den Callback für das Ereignis "Notation Declaration".
xml_set_unparsed_entity_decl_handler($parser, <handler>)
registriert den Callback für das Ereignis "Unparsed Entity Declaration".
xml_set_default_handler($parser, <handler>)
registriert einen Callback, der für all jene Ereignisse aufgerufen
wird, für die kein eigener Callback registriert wurde.
+ Standard, wenn auch nicht vom World Wide Web Consortium.
+ Geringer Speicherverbrauch, da immer nur das aktuelle XML-Element verfügbar ist.
+ Schnell.
- Lineare Verabeitung, kein beliebiger Zugriff auf Elemente möglich.
- Kein Schreibzugriff möglich.
- Programmierer muss sich um Buchhaltung kümmern.