HTML Parsen mit dem IPhone
Für ein aktuelles IPhone-Projekt musste ich eine große Webseite mit nicht wohlgeformten HTML-Code parsen und bin unvorhergesehen auf viele Probleme gestoßen. Begonnen habe ich mit den Hausmitteln der IPhone SDK, der Cocoa Objective-C Klasse NSXMLParser, die wie alle anderen verfügbaren Parser für das IPhone auf der C-Bibliothek libxml2 basiert. Der NSXMLParser gehört zu den SAX-Parsern (“Simple API for XML“), d.h. er durchläuft das XML-Dokument sequentiell und löst bei XML-Konstrukten, wie z.B. öffnenden oder schließenden Tags, bestimmte Ereignisse aus, die vom Programm ausgewertet werden können. Es stellte sich jedoch schnell heraus, dass NSXMLParser nur für die Verarbeitung von kleineren XML-Dokumenten geeignet ist und nur mit XHTML-Code zurecht kommt. Bei nicht wohlgeformten HTML-Code wurden Teile falsch oder gar nicht erkannt und in einigen Fällen kam es sogar zu Speicherzugriffsfehlern in der Klasse.
Als nächstes bin ich auf die DOM-Parser-Implementierung XPathQuery gestoßen. Im Vergleich zu SAX wird bei DOM (“Document Object Model“) das komplette Dokument eingelesen und eine Baumstruktur im Speicher aufgebaut, über die man auf die verschiedenen Knoten und Elemente des XML-Dokuments zugreifen kann. XPathQuery unterstützt neben XML explizit auch das Parsen von HTML und kommt auch mit nicht wohlgeformten HTML-Code zurecht. Doch erste Tests auf der IPhone Hardware machte schnell deutlich, dass das Erstellen eines DOM-Trees mit Objective-C Objekten für ein über 800kb großes HTML-Dokument mit 10MB Speicherverbrauch und über 15 Sekunden Parse-Zeit die falsche Wahl auf dem IPhone ist.
Nach weiteren DOM-basierten Parsern (Übersicht im Techstories-Wiki), die ich eventuell in einem späteren Blog-Eintrag vorstellen werde, bin ich schließlich auf die Klasse AQXMLParser aufmerksam geworden. AQXMLParser baut auf NSXMLParser auf und löst die folgenden Probleme von NSXMLParser:
- Inkrementelles Einlesen von XML-Dokumenten, dadurch geringerer Speicherverbrauch und Parsen während des Downloads möglich
- Parsen von nicht wohlgeformten HTML-Code
Leider ist aber auch diese Klasse nicht ganz fehlerfrei. Folgende Probleme konnte ich jedoch mit einem Patch beheben:
- Speicherzugriffsfehler beim Einlesen eines kompletten Dokuments
- Abbruch des kompletten Parse-Vorgangs bei Parser-Fehlern (ist jetzt über die Methode setAbortOnErrors konfigurierbar)
Mit der gepatchten AQXMLParser-Klasse steht eine performante und ressourcen- effektive Lösung für das Parsen von großen, nicht wohlgeformten HTML- und natürlich auch XML-Dokumenten auf dem IPhone zur Verfügung. Bei kleineren Dokumenten kommen jedoch auch DOM-basierte Parser in Frage, da sie meist einfacher zu implementieren sind.
Weitere Details und Beispiel Implementierungen finden sich im Wiki. Der Patch kann direkt hier heruntergeladen werden.

