2009-04-12 3 views
0

Kommen wir direkt zu meiner Frage: Ich habe einen Socket und alle Eingaben, die über diesen Socket/Stream kommen, werden von meinem SAX-Parser analysiert. Jetzt, nach einem bestimmten Parser-Ereignis, möchte ich den Socket/Stream innerhalb meines SAX-Event-Handlers schließen. Außerdem möchte ich den Stream von außen in einem bestimmten Fall schließen, während der Parser noch arbeitet. Leider kann ich das eine oder das andere nicht tun, ohne dass eine Ausnahme vom Parser ausgelöst wird (unerwartetes Dokumentende ...). Ok, ich könnte diese Ausnahme verstehen, aber weißt du eine Lösung wie man den Stream sicher schließt?Die beste Möglichkeit, einen Stream zu schließen, den ein SAX-Parser während des Parsing-Prozesses liest?

Antwort

3

Ich glaube nicht, dass Sie dies leicht tun können. Sie geben dem SAX-Parser eine Ressource (einen Stream) zum Lesen, und dann schließen Sie ihn, und der SAX-Parser erwartet immer noch, von ihm zu lesen - daher wirft er (nicht unbegründet!) Eine "unerwartete Dokumentenendung".

Wenn Sie dies sauber machen möchten, denke ich, dass Ihr SAX-Parser handler, den Sie implementiert haben, Ereignisse stillschweigend schlucken sollte, sobald Sie entschieden haben, weitere Ereignisse zu ignorieren.

z.B. Ihre Implementierungen von startElement(), endElement() usw. sollten vor der Verarbeitung prüfen, ob Sie an diesen Ereignissen interessiert sind.

Auf diese Weise kann der SAX-Parser sauber bis zum Ende des Dokuments ausgeführt werden, ohne dass Sie weitere Ereignisse verarbeiten müssen.

Oder warum notieren Sie nicht die Tatsache, dass Sie den Eingabestrom geschlossen haben, und dann, wenn Sie ein Ereignis 'unerwartete Dokumentendung' erhalten, sehen Sie, ob es wurde erwartet. Und nur einen Fehler protokollieren, wenn es wirklich unerwartet war.

+0

Ich mag das, vorausgesetzt, das Dokument hat jemals ein "Ende", da es nur Daten sind, die über einen Sockel kommen. Ansonsten fangen Sie einfach die Ausnahme ab. –

0

Wenn Sie das Ende der Dokumentgenerierung steuern, können Sie eine Close-Request-Nachricht einrichten, die an den Server zurückgesendet wird und das eingehende Dokument beendet. Abhängig von den Details Ihres kompletten Systems, ist dies entweder ein hässlicher Hack oder eine elegante Lösung ... :)

0

Das mag offensichtlich sein, aber für den Anwendungsfall wie diesen könnte ein Stax parser besser passen. Da die Anwendung das Lesen über Iteration steuert, kann sie den Parser und den zugrunde liegenden Stream an jedem beliebigen Punkt schließen. Mit SAX müssen Sie eine Ausnahme werfen, die nicht besonders elegant oder effizient ist. Außerdem können Sie das nur innerhalb des Handlers tun.

Für zusätzliche Punkte kann StaxMate Stax angenehmer nutzen; ohne sie hat Stax ein ähnlich niedriges Abstraktionsniveau wie SAX.

Endlich: Wenn Ihr Problem ist das Blockieren aufgrund von Sockets, kann es schwierig sein, mit traditionellen Blockierung-IO-basierten XML-Parsern zu lösen. Es gibt einen Open-Source-XML-Parser, der nicht-blockierendes (asynchrones) Parsing durchführen kann, aber das ist eher wenig bekannt, also werde ich diese Entdeckung interessierten Lesern überlassen. :-)

Verwandte Themen