Halihallo Andreas
oder habe ich das jetzt falsch verstanden: "RealCharacterData()" soll den bisherigen Inhaltsstring - der ja jetzt komplett ist, weil eine andere Funktion aufgerufen wurde - so umformen, wie ich ihn haben will? Also ich rufe "RealCharacterData()" aus "start()" heraus als erstes auf?
Ich glaube nicht ganz:
Wenn du den normalen Callback CharacterData() verwendest bekommst du
wie bereits festgestellt die Text-Stückchen happenweise zugesendet...
Daran wird sich auch nichts ändern, da du die Expat-Internals nicht
verändern kannst/willst.
Was ich nun vorschlage ist ein zweiter "externer" Callback zu
definieren, welcher nur dann aufgerufen wird, wenn ein Text-Stück
"komplett" also normalisiert ist. Wie kann dies umgesetzt werden?
Nun, wie ist ein ganzes Text-Stück definiert?
<definition type="versuch">
Es wird solange Text eingelesen, bis z.B. ein Element, Kommentar o.ä.
auftaucht. D.h. die vom CharacterData() Callback [Expat-Callback!]
gelieferten Texte werden solange zusammengehängt, bis ein Element
oder Kommentar (oder PI) auftaucht.
</definition>
Nun gut, das heisst für unseren Expat-CharacterData-Callback, dass
er die ankommenden Textstückchen solange in einer globalen Variable
"zusammenbastelt", bis dann einmal ein anderer Callback ausgelöst
wird.
Falls dann also ein anderer Callback ausgelöst wird
(Element,PI,Comment), ist der normalisierte Text, der sich in der
globalen Variablen angesammelt hat, fertig. Bevor jetzt aber
irgendwelche Aktionen für das Verarbeiten des Elementes/Kommentar
ausgeführt werden, muss dein Programm den normalisierten String
verarbeiten => ein "NormalizedCharacterData()" Callback muss
ausgelöst werden (dieser kommt jetzt aber nicht von Expat, sondern
von deinem Programm selber).
Dieser NormalizedCharacterData() Callback wird von jedem
Callback (ausser dem "Standard-Data-Callback") ausgelöst werden, denn
das ist ja unsere Definition von "normalisiertem Text", erst wenn
dein Programm den NormalizedCharacterData() verarbeitet hat, wird
der eigentliche Callback von Expat ausgeführt (Comment|Element etc).
Lange Rede kurzer Sinn. Ein Beispiel spricht 1000 Worte:
xml_set_character_data_handler( $parser, "CharacterData" );
xml_set_element_handler($xml_parser, "StartElement", "EndElement");
xml_set_processing_instruction_handler($xml_parser, "PIData");
...
function CharacterData($parser,$data) {
global $normalizedString;
// Normalisierungsprozess ist hier:
$normalizedString .= $data;
// Keine weitere Verarbeitung! - Der normalisierte String wird
// NormalizedCharacterData() verarbeitet!
}
function StartElement($parser,$name,$attributes) {
// Wurde vor dem Start dieses Elementes irgendwelche CDATA's
// empfangen? - So können diese (zusammengehängt in $normStr)
// dem NormalizedCharacterData()-Callback übergeben werden und
// dort so verarbeitet werden, als wäre es der normale
// Expat-Callback für 'Char'.
if (strlen($normalizedString)) {
NormalizedCharacterData($parser,$normalizedString);
$normalizedString = '';
}
// hier jetzt das "normale Verarbeiten von StartElement".
echo("found element $name\n");
}
function EndElement($parser,$name) {
if (strlen($normalizedString)) {
NormalizedCharacterData($parser,$normalizedString);
$normalizedString = '';
}
// hier jetzt das "normale Verarbeiten von EndElement".
echo("element end for $name\n");
}
function PIData($parser,$target,$data) {
if (strlen($normalizedString)) {
NormalizedCharacterData($parser,$normalizedString);
$normalizedString = '';
}
// hier jetzt das "normale Verarbeiten von PIData".
echo("ProcessingInstruction for $target with $data.\n");
}
function NormalizedCharacterData($parser,$data) {
// so, das ist jetzt unser "erweiterter CharacterData-Callback"
// hier kommen aber nur die wirklich normalisierten Strings hin!
// hier einfach das hinschreiben, was du sonst in den Expat-
// 'Char'-Handler geschrieben hättest.
echo("Endlich habe ich die TextNodes normalisiert: $data\n");
}
Das ist jetzt alles ungetestet. Es sollte aber so (ggf. mit kleinen
Anpassungen) funktionieren...
Ich hoffe, du weisst jetzt, was ich mit Worten vergeblich versucht
habe zu erklären (das ligt nicht an dir - Programmieren konnte ich
schon immer besser als Reden :-) - Nicht zuletzt, weil meine
Muttersprache Perl ist...).
Viele Grüsse
Philipp
The only program that runs perfectly every time, is a virus.