Tag Archives: Objective-C

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.

USB Panic Button unter Linux

USB Panic Button
Wäre es nicht schön bestimmte EDV Prozesse möglichst einfach und ohne Tastatureingabe anstoßen zu können? Genau dieses kann mit dem IT-Spielzeug USB Panic Button realisiert werden. Auf Knopfdruck Server oder Webanwendungen neu starten, per Instant Messaging Benutzergruppen über gleiche und wiederkehrende Dinge informieren oder für ganz Paranoide, verschlüsselte Linux-Partitionen unmounten und mit Nullen überschreiben lassen ;-)

Das erste Anwendungsbeispiel (Neustart von Webanwendungen) war Auslöser für meinen Kauf des USB-Geräts. Eine sich auf Grund von application loops und memory leaks ständig aufhängende Webanwendung konnte so für eine Übergangszeit durch die Nutzer der Anwendung selbst neugestartet werden, bis der Hersteller die Probleme gelöst hatte. Positiver Effekt: Die Mitarbeiter freuten sich anfangs regelrecht, wenn die Anwendung wieder hing und sie durch das zeremonielle Betätigen des Panic Buttons im IT-Büro das Problem selbst lösen konnten :-)

Doch leider wird der Panic Button nur mit einer Windows Software ausgeliefert, die lediglich ein Screenshot im Vollbild anzeigt, wenn der Knopf betätigt wurde. Voreingestellt ist ein Screenshot von einem offenen Excel Sheet, dass fleißiges Arbeiten suggerieren soll, wenn der Chef um die Ecke kommt (Chef-Taste). Meines Erachtens eher nutzlos.

Daher habe ich mit USB Sniffertools die Kommunikation zwischen der Windows Software und dem Button mitgeschnitten und analysiert, um eine eigene Software zu entwickeln, die auch andere Aktionen beim Betätigen der Taste durchführen kann. Das Ergebnis ist das Perl-Modul USB::Device::PanicButton, mit dem recht einfach das Gerät unter Linux, prinzipiell aber auch unter Windows ausgelesen werden kann.

Weitere Details zum Perl-Modul und Beispielcodes für C (libhid & libusb), Perl (USB::Device) und CoreFoundation (Mac OS X) findet sich im Wiki.

Ich bin gespannt auf eure Einsatzgebiete und Ideen :)