XML-Daten trotz Fehlern verarbeiten

Pendergast

Erfahrenes Mitglied
Servus,

ich möchte innerhalb eines PHP-Skriptes XML-Daten verarbeiten. Leider kann ich mich nicht darauf verlassen, dass die empfangenen XML-Daten gültig sind, so wie beispielsweise in diesem Dokument.

Ich habe noch keinen Weg gefunden, wie ich ein solch fehlerhaftes Dokument trotzdem mit den DOM-Klassen verarbeiten kann. Hat hier jemand eine Idee?

Zum Reproduzieren hab ich hier noch einen kleinen Codeschnipsel:
PHP:
$doc = new DomDocument();
$doc->load('http://univis.tum.de/prg?search=lectures&sem=2006s&show=xml&name=BWL%202:%20Organisation');
$lectures = $doc->getElementsByTagName('Lecture');
foreach ($lectures as $param) {
   echo $param->getAttribute('key').'<br>';
}

Besagter Code liefert leider nur die Warnung, dass ein ungültiges Zeichen in der XML-Datei gefunden wurde (hier: ). Ich kann leider nicht vorhersehen, was für wirre Zeichen sonst noch in diesen Dateien auftauchen, sonst würde ich sie natürlich einfach vorher rauslöschen. Am liebsten wäre mir eine Möglichkeit, in der ich das ungültige XML einfach trotzdem verarbeiten kann - nur wie gesagt dafür noch keine Lösung gefunden.
 
Vielleicht solltest Du die Inhalte zwischen den Feldern vorher codieren via urlencode bzw htmlentities oder iconv, catchen mit preg_all / regex Zeugs (oder nachher)

Generell sollte der Sender für eine korrekte Codierung sorgen, sonst läufst Du Gefahr dass sich eine XML Datei komplett zerschießt wegen < und >

Mein Vorschlag wäre wenn Sender seine Daten nicht ändern will

a) Simulationsdaten erstellen mit fehlerhaften Daten von Zeichen bis zu XML Tags im Fließtext die alles zerstören könnten
b) Kontrollroutinen schreiben die diese Situationen ermitteln und abfangen
c) uU vorher Elementinhalte zwischen den Tags recodieren

Man kann sehr gut mit iconv transformieren, zb ASCII UTF-8 / UNICODE
 
Nachdem ich die Hoffnung aufgegeben habe, jemand kennt irgendein undokumentiertes Option-Flag, mit dem ich Charakterfehler ignorieren lassen kann, hab ich mich nun für deine Lösung b) entschieden und lösche einfach alle codierten Steuerzeichen aus dem XML, das ich vorher mit file_get_contents() lade, durch unten stehende Methode jage und dann erst als String in das XML-Objekt überführe.

PHP:
private function removeIllegalCharacters($inText)
{
    function ponder($inChr)
    {
        if ($inChr{0} == 'x')
        {
            $inChr = hexdec($inChr);
        }
        if ($inChr <= 0x20 || ($inChr >= 0x7F && $inChr <= 0xA0))
        {
            return '';
        }
        return '&#x'.dechex($inChr).';';
    }
    $pattern = '/&#(x[a-f\d]{1,2}|[\d]{1,3});/ie';
    return preg_replace($pattern, "ponder('\\1')", $inText);
}
 
Zurück