Sven Rautenberg: Umlaute bei SAX

Beitrag lesen

Moin!

function character_handler($xml, $data)
{
if ($GLOBALS['tag'] != 'titel') return;
$GLOBALS['titel'][] = $data;

An dieser Stelle legst du ein potentiell mehrelementiges Array an, welches Teile des Inhalts des titel-Elements enthält. Nämlich für jedes geparste Bruchstück, was SAX ausspuckt, eines.

Das entspricht vollkommen der Funktionsweise von SAX.
»»

Ja, so soll es auch sein. Jeder Textknoten von den titel-Tags soll einen eigenen Eintrag in dem Array $titel haben. Aber es wird bei jedem Umlaut eine neues Ereignis für character_handler ausgelöst, was keinen Sinn macht. In Deinen Worten drei statt zwei Bruchstücken:

<titel>Entität</titel>
<titel>Tabelle</titel>

soll logischerweise zwei Ereignisse auslösen, es sind aber drei. Dabei wird das Array natürlich zu groß, statt zwei Einträgen drei.

Deine Beobachtung entspricht aber vollkommen der dokumentierten Funktionsweise von SAX. Es handelt sich hierbei um einen eventgesteuerten XML-Parser, d.h. du fütterst in ihn ein Fragment von XML hinein, und er parst das Stück und ruft intern passend zu den gefundenen Teilen die entsprechenden Funktionen auf, welche dann die gewünschten Maßnahmen ergreifen, um das XML-Fragment in geeigneten anderen Datenstrukturen zu speichern.

Dein Irrtum liegt darin, dass du glaubst, für den Textblock "Entität" würde dein Eventhandler für "character data" garantiert nur ein einziges Mal aufgerufen. Diese Annahme ist falsch. SAX könnte durchaus deinen Eventhandler für jeden Buchstaben einzeln aufrufen! Das muß dein Code berücksichtigen, er muß sich also merken, ob das Elementende "</titel>" schon gefunden wurde - solange das nicht der Fall ist, muß deine Funktion für Character Data alle gefundenen Zeichen sammeln und in einen String speichern.

Diese Vorgehensweise ist übrigens in der PHP-Doku auch beschrieben.

Außerdem: Dein Code enthält nirgendwo den Ausgabeteil. In dem wird vermutlich der Grund für den zerhauenen Umlaut drinstehen.

Den habe ich, weil er nichts zur Sache tut, weggelassen. Aber daran liegt es garantiert nicht:

foreach($titel as $titel)
  echo $titel;

Ohne Angaben zum Encoding wird der Browser "irgendwas" benutzten - in deinem Fall wohl ISO-8859-1.

Das hat in der Tat nichts mit der Zweiteiligkeit deines Parsergebnisses zu tun, aber mit der falschen Ausgabe des Umlauts schon.

- Sven Rautenberg

--
"Love your nation - respect the others."